diff --git a/README.md b/README.md index 3b6281d464..29571293b2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ *Youtube* is a library written in Rust to help interacting with your youtube account. For now, all functionality is geared towards allowing interruptible video uploads -and adjustments of video meta-data. \ No newline at end of file +and adjustments of video meta-data. + +The library works using the builder pattern. If builders are instantiated, you will need to +provide the minimal information right off the bat. Further calls to the builder allow +to configure it. Some configuration will be in the form of callbacks, which allows you to +control internal loops or behaviour. + +It's the goal of each builder to maximize the chances of a successful result, and it will +provide enough callbacks to be resilient against network errors, and authorization failures +which require the token to be refreshed. + +You will need authorization to perform most of the operations implemented here - it can be obtained +and handled using the [yup-oauth2 library][oauth]. + +[oauth]: [https://crates.io/crates/yup-oauth2] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index a93251b65d..c72499ca3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,68 @@ -#[test] -fn it_works() { +#![feature(core)] +//! # Usage +//! ```test_harness +//! extern crate youtube3; +//! extern crate hyper; +//! +//! # #[test] +//! # fn test() { +//! let youtube = youtube3::new(hyper::Client::new()); +//! youtube.videos(); +//! # } +extern crate hyper; +extern crate "rustc-serialize" as rustc_serialize; + +use std::marker::PhantomData; +use std::borrow::BorrowMut; +use std::cell::RefCell; + +mod common; +pub mod videos; + + +/// Central instance to access all youtube related services +pub struct YouTube { + client: RefCell, + + _m: PhantomData } + +impl<'a, C, NC> YouTube + where NC: hyper::net::NetworkConnector, + C: BorrowMut> + 'a { + + pub fn new(client: C) -> YouTube { + YouTube { + client: RefCell::new(client), + _m: PhantomData, + } + } + + pub fn videos(&'a self) -> videos::Service<'a, C, NC> { + videos::Service::new(&self.client) + } +} + + +pub fn new(client: C) -> YouTube + where NC: hyper::net::NetworkConnector, + C: BorrowMut> { + YouTube::new(client) +} + +#[cfg(test)] +mod tests { + use super::*; + use hyper; + + + #[test] + fn instantiate() { + let yt = YouTube::new(hyper::Client::new()); + let v = yt.videos(); + + let mut c = hyper::Client::new(); + let yt = YouTube::new(&mut c); + let v = yt.videos(); + } +} \ No newline at end of file diff --git a/src/videos/service.rs b/src/videos/service.rs index 5bb2dc15ad..00b04fd716 100644 --- a/src/videos/service.rs +++ b/src/videos/service.rs @@ -6,6 +6,67 @@ use rustc_serialize; use hyper; +/// Reresents all aspects of a youtube video resource. May only be partially +/// available +#[derive(RustcEncodable, RustcDecodable, Default, Clone)] +pub struct Video { + pub snippet: Option, + pub recordingDetails: Option, + pub status: Option, +} + +#[allow(non_snake_case)] +#[derive(RustcEncodable, RustcDecodable, Default, Clone)] +pub struct VideoSnippet { + pub categoryId: String, + pub description: String, + pub tags: Vec, + pub title: String, + + pub status: Option, + pub recordingDetails: Option, +} + +impl Video { + fn parts(&self) -> String { + let mut res = String::new(); + if self.status.is_some() { + res = res + "status,"; + } + if self.recordingDetails.is_some() { + res = res + "recordingDetails"; + } + if self.snippet.is_some() { + res = res + "snippet,"; + } + res + } +} + +#[allow(non_snake_case)] +#[derive(RustcEncodable, RustcDecodable, Default, Clone)] +pub struct VideoStatus { + pub privacyStatus: String, + pub embeddable: bool, + pub license: String, + pub publicStatsViewable: bool, + pub publishAt: String, +} + +#[allow(non_snake_case)] +#[derive(RustcEncodable, RustcDecodable, Default, Clone)] +pub struct VideoRecordingDetails { + locationDescription: String, + recordingDate: String, +} + +#[allow(non_snake_case)] +#[derive(RustcEncodable, RustcDecodable, Default, Clone)] +pub struct GeoPoint { + altitude: f64, + latitude: f64, + longitude: f64, +} /// The videos service - provides actual functionality through builders. pub struct Service<'a, C, NC> @@ -27,13 +88,53 @@ impl<'a, C, NC> Service<'a, C, NC> _m: PhantomData, } } + + pub fn insert(&self, parts: &str, video: &Video) -> VideosInsertBuilder<'a, C, NC> { + VideosInsertBuilder { + client: self.client, + video: video.clone(), + parts: parts.to_string(), + _m: PhantomData, + } + } +} + +pub struct VideosInsertBuilder<'a, C, NC> + where NC: 'a, + C: 'a { + + client: &'a RefCell, + video: Video, + parts: String, + + _m: PhantomData +} + + +impl<'a, C, NC> VideosInsertBuilder<'a, C, NC> + where NC: hyper::net::NetworkConnector, + C: BorrowMut> + 'a { + } #[cfg(test)] mod tests { + use std::default::Default; + use super::*; + use hyper; + use std::cell::RefCell; + + #[test] + fn insert() { + let c = RefCell::new(hyper::Client::new()); + let s = Service::new(&c); + let v =