From aaf432fb545b47a64692dda0296414edbf3017b6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 28 Feb 2015 19:13:51 +0100 Subject: [PATCH] feat(videos): first primitive types and api Now it should be possible to implement first version of actual insert handling, with everything there is about it. That should eventually help to generalize it, as I am definitely not going to hand-implemented these protocols ... . The great thing is, that if done right, one will be able to truly be first and make an impact ! --- README.md | 16 ++++++- src/lib.rs | 69 ++++++++++++++++++++++++++++- src/videos/service.rs | 101 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 3 deletions(-) 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 =