diff --git a/Cargo.lock b/Cargo.lock index 05484d5..2fa58d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,9 +5,9 @@ dependencies = [ "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "yup-hyper-mock 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -50,6 +50,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -79,6 +80,11 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dtoa" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "foreign-types" version = "0.2.0" @@ -144,7 +150,7 @@ dependencies = [ [[package]] name = "itoa" -version = "0.1.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -270,6 +276,11 @@ name = "pkg-config" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rand" version = "0.3.15" @@ -283,11 +294,6 @@ name = "redox_syscall" version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rustc_version" version = "0.1.7" @@ -346,17 +352,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "0.7.15" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "serde_json" -version = "0.7.4" +name = "serde_derive" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -409,6 +453,11 @@ name = "unicode-normalization" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.4.1" @@ -461,6 +510,7 @@ dependencies = [ "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" +"checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" "checksum gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)" = "5f837c392f2ea61cb1576eac188653df828c861b7137d74ea4a5caa89621f9e6" "checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" @@ -468,7 +518,7 @@ dependencies = [ "checksum hyper 0.10.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cb7031283266d12f2d4bf30b624bc2b2fd21bbcc00863c9928e87dc5e1699d2e" "checksum hyper-native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "48fecce9e67dff46707980abb41f10eaa49cf0eded8dd0c26ae94b3ae5c3f705" "checksum idna 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2233d4940b1f19f0418c158509cd7396b8d70a5db5705ce410914dc8fa603b37" -"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1" +"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" @@ -485,17 +535,21 @@ dependencies = [ "checksum openssl 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b34cd77cf91301fff3123fbd46b065c3b728b17a392835de34c397315dce5586" "checksum openssl-sys 0.9.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e035022a50faa380bd7ccdbd184d946ce539ebdb0a358780de92a995882af97a" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" "checksum redox_syscall 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "3041aeb6000db123d2c9c751433f526e1f404b23213bd733167ab770c3989b4d" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum schannel 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4e45ac5e9e4698c1c138d2972bedcd90b81fe1efeba805449d2bdd54512de5f9" "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "42ddf098d78d0b64564b23ee6345d07573e7d10e52ad86875d89ddf5f8378a02" "checksum security-framework-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "5bacdada57ea62022500c457c8571c17dfb5e6240b7c8eac5916ffa8c7138a55" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum serde 0.7.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1b0e0732aa8ec4267f61815a396a942ba3525062e3bd5520aa8419927cfc0a92" -"checksum serde_json 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b22e8a0554f31cb0f501e027de07b253553b308124f61c57598b9678dba35c0b" +"checksum serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4" +"checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3" +"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" +"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" @@ -503,6 +557,7 @@ dependencies = [ "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a6a2c4e3710edd365cd7e78383153ed739fa31af19f9172f72d3575060f5a43a" "checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum url 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2ba3456fbe5c0098cb877cf08b92b76c3e18e0be9e47c35b487220d377d24e" "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum version_check 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2bb3950bf29e36796dea723df1747619dd331881aefef75b7cf1c58fdd738afe" diff --git a/Cargo.toml b/Cargo.toml index 6281712..c7878be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,20 +12,14 @@ documentation = "https://cmcenroe.me/inth-oauth2/inth_oauth2" repository = "https://github.com/programble/inth-oauth2" readme = "README.md" -[features] -default = ["serde"] - [dependencies] -chrono = "0.3" +chrono = { version = "0.3", features = ["serde"] } hyper = "0.10" -rustc-serialize = "0.3.16" +serde = "1.0.8" +serde_derive = "1.0.5" +serde_json = "1.0.2" url = "1.1.0" -[dependencies.serde] -version = "0.7.0" -optional = true - [dev-dependencies] hyper-native-tls = "0.2" -serde_json = "0.7.0" yup-hyper-mock = "2.0" diff --git a/src/client/error.rs b/src/client/error.rs index 2b39579..c8ae57c 100644 --- a/src/client/error.rs +++ b/src/client/error.rs @@ -2,7 +2,7 @@ use std::error::Error; use std::{fmt, io}; use hyper; -use rustc_serialize::json; +use serde_json; use url; use client::response::ParseError; @@ -18,7 +18,7 @@ pub enum ClientError { /// Hyper error. Hyper(hyper::Error), /// JSON error. - Json(json::ParserError), + Json(serde_json::Error), /// Response parse error. Parse(ParseError), /// OAuth 2.0 error. @@ -75,6 +75,6 @@ macro_rules! impl_from { impl_from!(ClientError::Io, io::Error); impl_from!(ClientError::Url, url::ParseError); impl_from!(ClientError::Hyper, hyper::Error); -impl_from!(ClientError::Json, json::ParserError); +impl_from!(ClientError::Json, serde_json::Error); impl_from!(ClientError::Parse, ParseError); impl_from!(ClientError::OAuth2, OAuth2Error); diff --git a/src/client/mod.rs b/src/client/mod.rs index 032efd5..0a9764b 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use hyper::{self, header, mime}; -use rustc_serialize::json::Json; +use serde_json::{self, Value}; use url::Url; use url::form_urlencoded::Serializer; @@ -105,7 +105,7 @@ impl Client

{ &'a self, http_client: &hyper::Client, mut body: Serializer - ) -> Result { + ) -> Result { if P::credentials_in_body() { body.append_pair("client_id", &self.client_id); body.append_pair("client_secret", &self.client_secret); @@ -129,7 +129,7 @@ impl Client

{ .body(&body); let mut response = try!(request.send()); - let json = try!(Json::from_reader(&mut response)); + let json = serde_json::from_reader(&mut response)?; let error = OAuth2Error::from_response(&json); diff --git a/src/client/response.rs b/src/client/response.rs index bbba40e..c48d26b 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -3,19 +3,19 @@ use std::error::Error; use std::fmt; -use rustc_serialize::json::{self, Json}; +use serde_json::Value; /// Response parsing. pub trait FromResponse: Sized { /// Parse a JSON response. - fn from_response(json: &Json) -> Result; + fn from_response(json: &Value) -> Result; /// Parse a JSON response, inheriting missing values from the previous instance. /// /// Necessary for parsing refresh token responses where the absence of a new refresh token /// implies that the previous refresh token is still valid. #[allow(unused_variables)] - fn from_response_inherit(json: &Json, prev: &Self) -> Result { + fn from_response_inherit(json: &Value, prev: &Self) -> Result { FromResponse::from_response(json) } } @@ -54,42 +54,3 @@ impl fmt::Display for ParseError { impl Error for ParseError { fn description(&self) -> &str { "response parse error" } } - -/// JSON helper for response parsing. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct JsonHelper<'a>(pub &'a Json); - -impl<'a> JsonHelper<'a> { - /// Returns self as a `JsonObjectHelper` or fails with `ParseError::ExpectedType`. - pub fn as_object(&self) -> Result, ParseError>{ - self.0.as_object() - .ok_or_else(|| ParseError::ExpectedType("object")) - .map(|o| JsonObjectHelper(o)) - } -} - -/// JSON object helper for response parsing. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct JsonObjectHelper<'a>(pub &'a json::Object); - -impl<'a> JsonObjectHelper<'a> { - /// Gets a field as a string or returns `None`. - pub fn get_string_option(&self, key: &'static str) -> Option<&'a str> { - self.0.get(key).and_then(Json::as_string) - } - - /// Gets a field as a string or fails with `ParseError::ExpectedFieldType`. - pub fn get_string(&self, key: &'static str) -> Result<&'a str, ParseError> { - self.get_string_option(key).ok_or_else(|| ParseError::ExpectedFieldType(key, "string")) - } - - /// Gets a field as an i64 or returns `None`. - pub fn get_i64_option(&self, key: &'static str) -> Option { - self.0.get(key).and_then(Json::as_i64) - } - - /// Gets a field as an i64 or fails with `ParseError::ExpectedFieldType`. - pub fn get_i64(&self, key: &'static str) -> Result { - self.get_i64_option(key).ok_or_else(|| ParseError::ExpectedFieldType(key, "i64")) - } -} diff --git a/src/error.rs b/src/error.rs index 4407449..f3427e1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,9 +3,9 @@ use std::error::Error; use std::fmt; -use rustc_serialize::json::Json; +use serde_json::Value; -use client::response::{FromResponse, ParseError, JsonHelper}; +use client::response::{FromResponse, ParseError}; /// OAuth 2.0 error codes. /// @@ -87,12 +87,14 @@ impl Error for OAuth2Error { } impl FromResponse for OAuth2Error { - fn from_response(json: &Json) -> Result { - let obj = try!(JsonHelper(json).as_object()); + fn from_response(json: &Value) -> Result { + let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?; - let code = try!(obj.get_string("error")); - let description = obj.get_string_option("error_description"); - let uri = obj.get_string_option("error_uri"); + let code = obj.get("error") + .and_then(Value::as_str) + .ok_or(ParseError::ExpectedFieldType("error", "string"))?; + let description = obj.get("error_description").and_then(Value::as_str); + let uri = obj.get("error_uri").and_then(Value::as_str); Ok(OAuth2Error { code: code.into(), @@ -104,14 +106,12 @@ impl FromResponse for OAuth2Error { #[cfg(test)] mod tests { - use rustc_serialize::json::Json; - use client::response::{FromResponse, ParseError}; use super::{OAuth2Error, OAuth2ErrorCode}; #[test] fn from_response_empty() { - let json = Json::from_str("{}").unwrap(); + let json = "{}".parse().unwrap(); assert_eq!( ParseError::ExpectedFieldType("error", "string"), OAuth2Error::from_response(&json).unwrap_err() @@ -120,7 +120,7 @@ mod tests { #[test] fn from_response() { - let json = Json::from_str(r#"{"error":"invalid_request"}"#).unwrap(); + let json = r#"{"error":"invalid_request"}"#.parse().unwrap(); assert_eq!( OAuth2Error { code: OAuth2ErrorCode::InvalidRequest, @@ -133,7 +133,8 @@ mod tests { #[test] fn from_response_with_description() { - let json = Json::from_str(r#"{"error":"invalid_request","error_description":"foo"}"#) + let json = r#"{"error":"invalid_request","error_description":"foo"}"# + .parse() .unwrap(); assert_eq!( OAuth2Error { @@ -147,9 +148,9 @@ mod tests { #[test] fn from_response_with_uri() { - let json = Json::from_str( - r#"{"error":"invalid_request","error_uri":"http://example.com"}"# - ).unwrap(); + let json = r#"{"error":"invalid_request","error_uri":"http://example.com"}"# + .parse() + .unwrap(); assert_eq!( OAuth2Error { code: OAuth2ErrorCode::InvalidRequest, diff --git a/src/lib.rs b/src/lib.rs index c7502fa..804f292 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,37 +115,19 @@ //! //! ### Persisting tokens //! -//! All token types implement `Encodable` / `Decodable` from `rustc_serialize` and `Serialize` / -//! `Deserialize` from `serde` (with the default `serde` feature). -//! -//! ```no_run -//! # extern crate inth_oauth2; -//! # extern crate rustc_serialize; -//! # use inth_oauth2::Client; -//! # use inth_oauth2::provider::google::Installed; -//! use rustc_serialize::json; -//! # fn main() { -//! # let http_client = Default::default(); -//! # let client = Client::::new(String::new(), String::new(), None); -//! # let token = client.request_token(&http_client, "").unwrap(); -//! let json = json::encode(&token).unwrap(); -//! # } -//! ``` +//! All token types implement `Serialize` and `Deserialize` from `serde`. //! //! ```no_run //! # extern crate inth_oauth2; //! extern crate serde_json; //! # use inth_oauth2::Client; //! # use inth_oauth2::provider::google::Installed; -//! # #[cfg(feature = "serde")] //! # fn main() { //! # let http_client = Default::default(); //! # let client = Client::::new(String::new(), String::new(), None); //! # let token = client.request_token(&http_client, "").unwrap(); //! let json = serde_json::to_string(&token).unwrap(); //! # } -//! # #[cfg(not(feature = "serde"))] -//! # fn main() { } //! ``` #![warn( @@ -160,21 +142,18 @@ variant_size_differences )] +#[macro_use] +extern crate serde_derive; + extern crate chrono; extern crate hyper; -extern crate rustc_serialize; +extern crate serde_json; extern crate url; -#[cfg(feature = "serde")] -extern crate serde; - -pub use token::{Token, Lifetime}; -pub use client::{Client, ClientError}; - pub mod token; pub mod provider; pub mod error; pub mod client; -#[cfg(all(test, feature = "serde"))] -extern crate serde_json; +pub use token::{Token, Lifetime}; +pub use client::{Client, ClientError}; diff --git a/src/token/bearer.rs b/src/token/bearer.rs index 6cde937..1d7e102 100644 --- a/src/token/bearer.rs +++ b/src/token/bearer.rs @@ -1,13 +1,13 @@ use hyper::header; -use rustc_serialize::json::Json; +use serde_json::Value; use super::{Token, Lifetime}; -use client::response::{FromResponse, ParseError, JsonHelper}; +use client::response::{FromResponse, ParseError}; /// The bearer token type. /// /// See [RFC 6750](http://tools.ietf.org/html/rfc6750). -#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Bearer { access_token: String, scope: Option, @@ -27,16 +27,20 @@ impl<'a, L: Lifetime> Into> for &'a Bearer } impl Bearer { - fn from_response_and_lifetime(json: &Json, lifetime: L) -> Result { - let obj = try!(JsonHelper(json).as_object()); + fn from_response_and_lifetime(json: &Value, lifetime: L) -> Result { + let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?; - let token_type = try!(obj.get_string("token_type")); + let token_type = obj.get("token_type") + .and_then(Value::as_str) + .ok_or(ParseError::ExpectedFieldType("token_type", "string"))?; if token_type != "Bearer" && token_type != "bearer" { return Err(ParseError::ExpectedFieldValue("token_type", "Bearer")); } - let access_token = try!(obj.get_string("access_token")); - let scope = obj.get_string_option("scope"); + let access_token = obj.get("access_token") + .and_then(Value::as_str) + .ok_or(ParseError::ExpectedFieldType("access_token", "string"))?; + let scope = obj.get("scope").and_then(Value::as_str); Ok(Bearer { access_token: access_token.into(), @@ -47,123 +51,20 @@ impl Bearer { } impl FromResponse for Bearer { - fn from_response(json: &Json) -> Result { - let lifetime = try!(FromResponse::from_response(json)); + fn from_response(json: &Value) -> Result { + let lifetime = FromResponse::from_response(json)?; Bearer::from_response_and_lifetime(json, lifetime) } - fn from_response_inherit(json: &Json, prev: &Self) -> Result { - let lifetime = try!(FromResponse::from_response_inherit(json, &prev.lifetime)); + fn from_response_inherit(json: &Value, prev: &Self) -> Result { + let lifetime = FromResponse::from_response_inherit(json, &prev.lifetime)?; Bearer::from_response_and_lifetime(json, lifetime) } } -#[cfg(feature = "serde")] -mod serde { - use std::marker::PhantomData; - - use serde::{Serialize, Serializer, Deserialize, Deserializer}; - use serde::{ser, de}; - - use token::Lifetime; - use super::Bearer; - - impl Serialize for Bearer { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> { - serializer.serialize_struct("Bearer", SerVisitor(self, 0)) - } - } - - struct SerVisitor<'a, L: Lifetime + Serialize + 'a>(&'a Bearer, u8); - impl<'a, L: Lifetime + Serialize + 'a> ser::MapVisitor for SerVisitor<'a, L> { - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> { - self.1 += 1; - match self.1 { - 1 => serializer.serialize_struct_elt("access_token", &self.0.access_token).map(Some), - 2 => serializer.serialize_struct_elt("scope", &self.0.scope).map(Some), - 3 => serializer.serialize_struct_elt("lifetime", &self.0.lifetime).map(Some), - _ => Ok(None), - } - } - - fn len(&self) -> Option { Some(3) } - } - - impl Deserialize for Bearer { - fn deserialize(deserializer: &mut D) -> Result { - static FIELDS: &'static [&'static str] = &["access_token", "scope", "lifetime"]; - deserializer.deserialize_struct("Bearer", FIELDS, DeVisitor(PhantomData)) - } - } - - struct DeVisitor(PhantomData); - impl de::Visitor for DeVisitor { - type Value = Bearer; - - fn visit_map(&mut self, mut visitor: V) -> Result, V::Error> { - let mut access_token = None; - let mut scope = None; - let mut lifetime = None; - - loop { - match try!(visitor.visit_key()) { - Some(Field::AccessToken) => access_token = Some(try!(visitor.visit_value())), - Some(Field::Scope) => scope = Some(try!(visitor.visit_value())), - Some(Field::Lifetime) => lifetime = Some(try!(visitor.visit_value())), - None => break, - } - } - - let access_token = match access_token { - Some(s) => s, - None => return visitor.missing_field("access_token"), - }; - let lifetime = match lifetime { - Some(l) => l, - None => return visitor.missing_field("lifetime"), - }; - - try!(visitor.end()); - - Ok(Bearer { - access_token: access_token, - scope: scope, - lifetime: lifetime, - }) - } - } - - enum Field { - AccessToken, - Scope, - Lifetime, - } - - impl Deserialize for Field { - fn deserialize(deserializer: &mut D) -> Result { - deserializer.deserialize(FieldVisitor) - } - } - - struct FieldVisitor; - impl de::Visitor for FieldVisitor { - type Value = Field; - - fn visit_str(&mut self, value: &str) -> Result { - match value { - "access_token" => Ok(Field::AccessToken), - "scope" => Ok(Field::Scope), - "lifetime" => Ok(Field::Lifetime), - _ => Err(de::Error::custom("expected access_token, scope or lifetime")), - } - } - } -} - #[cfg(test)] mod tests { use chrono::{UTC, Duration}; - use rustc_serialize::json::Json; use client::response::{FromResponse, ParseError}; use token::{Static, Refresh}; @@ -171,7 +72,7 @@ mod tests { #[test] fn from_response_with_invalid_token_type() { - let json = Json::from_str(r#"{"token_type":"MAC","access_token":"aaaaaaaa"}"#).unwrap(); + let json = r#"{"token_type":"MAC","access_token":"aaaaaaaa"}"#.parse().unwrap(); assert_eq!( ParseError::ExpectedFieldValue("token_type", "Bearer"), Bearer::::from_response(&json).unwrap_err() @@ -180,7 +81,7 @@ mod tests { #[test] fn from_response_capital_b() { - let json = Json::from_str(r#"{"token_type":"Bearer","access_token":"aaaaaaaa"}"#).unwrap(); + let json = r#"{"token_type":"Bearer","access_token":"aaaaaaaa"}"#.parse().unwrap(); assert_eq!( Bearer { access_token: String::from("aaaaaaaa"), @@ -193,7 +94,7 @@ mod tests { #[test] fn from_response_little_b() { - let json = Json::from_str(r#"{"token_type":"bearer","access_token":"aaaaaaaa"}"#).unwrap(); + let json = r#"{"token_type":"bearer","access_token":"aaaaaaaa"}"#.parse().unwrap(); assert_eq!( Bearer { access_token: String::from("aaaaaaaa"), @@ -206,9 +107,9 @@ mod tests { #[test] fn from_response_with_scope() { - let json = Json::from_str( - r#"{"token_type":"Bearer","access_token":"aaaaaaaa","scope":"foo"}"# - ).unwrap(); + let json = r#"{"token_type":"Bearer","access_token":"aaaaaaaa","scope":"foo"}"# + .parse() + .unwrap(); assert_eq!( Bearer { access_token: String::from("aaaaaaaa"), @@ -221,14 +122,14 @@ mod tests { #[test] fn from_response_refresh() { - let json = Json::from_str(r#" + let json = r#" { "token_type":"Bearer", "access_token":"aaaaaaaa", "expires_in":3600, "refresh_token":"bbbbbbbb" } - "#).unwrap(); + "#.parse().unwrap(); let bearer = Bearer::::from_response(&json).unwrap(); assert_eq!("aaaaaaaa", bearer.access_token); assert_eq!(None, bearer.scope); @@ -240,23 +141,23 @@ mod tests { #[test] fn from_response_inherit_refresh() { - let json = Json::from_str(r#" + let json = r#" { "token_type":"Bearer", "access_token":"aaaaaaaa", "expires_in":3600, "refresh_token":"bbbbbbbb" } - "#).unwrap(); + "#.parse().unwrap(); let prev = Bearer::::from_response(&json).unwrap(); - let json = Json::from_str(r#" + let json = r#" { "token_type":"Bearer", "access_token":"cccccccc", "expires_in":3600 } - "#).unwrap(); + "#.parse().unwrap(); let bearer = Bearer::::from_response_inherit(&json, &prev).unwrap(); assert_eq!("cccccccc", bearer.access_token); assert_eq!(None, bearer.scope); @@ -265,19 +166,4 @@ mod tests { assert!(refresh.expires() > &UTC::now()); assert!(refresh.expires() <= &(UTC::now() + Duration::seconds(3600))); } - - #[cfg(feature = "serde")] - #[test] - fn serialize_deserialize() { - use serde_json; - - let original = Bearer { - access_token: String::from("foo"), - scope: Some(String::from("bar")), - lifetime: Static, - }; - let serialized = serde_json::to_value(&original); - let deserialized = serde_json::from_value(serialized).unwrap(); - assert_eq!(original, deserialized); - } } diff --git a/src/token/expiring.rs b/src/token/expiring.rs index a18808a..054b991 100644 --- a/src/token/expiring.rs +++ b/src/token/expiring.rs @@ -1,12 +1,11 @@ -use chrono::{DateTime, UTC, Duration, TimeZone}; -use rustc_serialize::json::Json; -use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; +use chrono::{DateTime, UTC, Duration}; +use serde_json::Value; use super::Lifetime; -use client::response::{FromResponse, ParseError, JsonHelper}; +use client::response::{FromResponse, ParseError}; /// An expiring token. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct Expiring { expires: DateTime, } @@ -21,14 +20,16 @@ impl Lifetime for Expiring { } impl FromResponse for Expiring { - fn from_response(json: &Json) -> Result { - let obj = try!(JsonHelper(json).as_object()); + fn from_response(json: &Value) -> Result { + let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?; - if obj.0.contains_key("refresh_token") { + if obj.contains_key("refresh_token") { return Err(ParseError::UnexpectedField("refresh_token")); } - let expires_in = try!(obj.get_i64("expires_in")); + let expires_in = obj.get("expires_in") + .and_then(Value::as_i64) + .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?; Ok(Expiring { expires: UTC::now() + Duration::seconds(expires_in), @@ -36,159 +37,18 @@ impl FromResponse for Expiring { } } -#[derive(RustcEncodable, RustcDecodable)] -struct Serializable { - expires: i64, -} - -impl<'a> From<&'a Expiring> for Serializable { - fn from(expiring: &Expiring) -> Self { - Serializable { - expires: expiring.expires.timestamp(), - } - } -} - -impl Into for Serializable { - fn into(self) -> Expiring { - Expiring { - expires: UTC.timestamp(self.expires, 0), - } - } -} - -impl Encodable for Expiring { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - Serializable::from(self).encode(s) - } -} - -impl Decodable for Expiring { - fn decode(d: &mut D) -> Result { - Serializable::decode(d).map(Into::into) - } -} - -#[cfg(feature = "serde")] -mod serde { - use chrono::{UTC, TimeZone}; - use serde::{Serialize, Serializer, Deserialize, Deserializer}; - use serde::{ser, de}; - - use super::Expiring; - - impl Serialize for Expiring { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> { - serializer.serialize_struct("Expiring", SerVisitor(self, 0)) - } - } - - struct SerVisitor<'a>(&'a Expiring, u8); - impl<'a> ser::MapVisitor for SerVisitor<'a> { - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> { - self.1 += 1; - match self.1 { - 1 => serializer.serialize_struct_elt("expires", &self.0.expires.timestamp()).map(Some), - _ => Ok(None), - } - } - - fn len(&self) -> Option { Some(1) } - } - - impl Deserialize for Expiring { - fn deserialize(deserializer: &mut D) -> Result { - static FIELDS: &'static [&'static str] = &["expires"]; - deserializer.deserialize_struct("Expiring", FIELDS, DeVisitor) - } - } - - struct DeVisitor; - impl de::Visitor for DeVisitor { - type Value = Expiring; - - fn visit_map(&mut self, mut visitor: V) -> Result { - let mut expires = None; - - loop { - match try!(visitor.visit_key()) { - Some(Field::Expires) => expires = Some(try!(visitor.visit_value())), - None => break, - } - } - - let expires = match expires { - Some(i) => UTC.timestamp(i, 0), - None => return visitor.missing_field("expires"), - }; - - try!(visitor.end()); - - Ok(Expiring { - expires: expires, - }) - } - } - - enum Field { - Expires, - } - - impl Deserialize for Field { - fn deserialize(deserializer: &mut D) -> Result { - deserializer.deserialize(FieldVisitor) - } - } - - struct FieldVisitor; - impl de::Visitor for FieldVisitor { - type Value = Field; - - fn visit_str(&mut self, value: &str) -> Result { - match value { - "expires" => Ok(Field::Expires), - _ => Err(de::Error::custom("expected expires")), - } - } - } -} - #[cfg(test)] mod tests { - use chrono::{UTC, Duration, Timelike}; - use rustc_serialize::json::{self, Json}; + use chrono::{UTC, Duration}; use client::response::FromResponse; use super::Expiring; #[test] fn from_response() { - let json = Json::from_str(r#"{"expires_in":3600}"#).unwrap(); + let json = r#"{"expires_in":3600}"#.parse().unwrap(); let expiring = Expiring::from_response(&json).unwrap(); assert!(expiring.expires > UTC::now()); assert!(expiring.expires <= UTC::now() + Duration::seconds(3600)); } - - #[test] - fn encode_decode() { - let expiring = Expiring { - expires: UTC::now().with_nanosecond(0).unwrap(), - }; - let json = json::encode(&expiring).unwrap(); - let decoded = json::decode(&json).unwrap(); - assert_eq!(expiring, decoded); - } - - #[cfg(feature = "serde")] - #[test] - fn serialize_deserialize() { - use serde_json; - - let original = Expiring { - expires: UTC::now().with_nanosecond(0).unwrap(), - }; - let serialized = serde_json::to_value(&original); - let deserialized = serde_json::from_value(serialized).unwrap(); - assert_eq!(original, deserialized); - } } diff --git a/src/token/mod.rs b/src/token/mod.rs index a245975..94f953d 100644 --- a/src/token/mod.rs +++ b/src/token/mod.rs @@ -29,14 +29,12 @@ pub trait Lifetime: FromResponse { fn expired(&self) -> bool; } -pub use self::bearer::Bearer; mod bearer; - -pub use self::statik::Static; +mod expiring; +mod refresh; mod statik; +pub use self::bearer::Bearer; pub use self::expiring::Expiring; -mod expiring; - pub use self::refresh::Refresh; -mod refresh; +pub use self::statik::Static; diff --git a/src/token/refresh.rs b/src/token/refresh.rs index 62ef4b6..503d1ed 100644 --- a/src/token/refresh.rs +++ b/src/token/refresh.rs @@ -1,12 +1,11 @@ -use chrono::{DateTime, UTC, Duration, TimeZone}; -use rustc_serialize::json::Json; -use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; +use chrono::{DateTime, UTC, Duration}; +use serde_json::Value; use super::Lifetime; -use client::response::{FromResponse, ParseError, JsonHelper}; +use client::response::{FromResponse, ParseError}; /// An expiring token which can be refreshed. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Refresh { refresh_token: String, expires: DateTime, @@ -27,11 +26,15 @@ impl Lifetime for Refresh { } impl FromResponse for Refresh { - fn from_response(json: &Json) -> Result { - let obj = try!(JsonHelper(json).as_object()); + fn from_response(json: &Value) -> Result { + let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?; - let refresh_token = try!(obj.get_string("refresh_token")); - let expires_in = try!(obj.get_i64("expires_in")); + let refresh_token = obj.get("refresh_token") + .and_then(Value::as_str) + .ok_or(ParseError::ExpectedFieldType("refresh_token", "string"))?; + let expires_in = obj.get("expires_in") + .and_then(Value::as_i64) + .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?; Ok(Refresh { refresh_token: refresh_token.into(), @@ -39,14 +42,17 @@ impl FromResponse for Refresh { }) } - fn from_response_inherit(json: &Json, prev: &Self) -> Result { - let obj = try!(JsonHelper(json).as_object()); + fn from_response_inherit(json: &Value, prev: &Self) -> Result { + let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?; - let refresh_token = try! { - obj.get_string("refresh_token") - .or(Ok(&prev.refresh_token)) - }; - let expires_in = try!(obj.get_i64("expires_in")); + let refresh_token = obj.get("refresh_token") + .and_then(Value::as_str) + .or(Some(&prev.refresh_token)) + .ok_or(ParseError::ExpectedFieldType("refresh_token", "string"))?; + + let expires_in = obj.get("expires_in") + .and_then(Value::as_i64) + .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?; Ok(Refresh { refresh_token: refresh_token.into(), @@ -55,147 +61,16 @@ impl FromResponse for Refresh { } } -#[derive(RustcEncodable, RustcDecodable)] -struct Serializable { - refresh_token: String, - expires: i64, -} - -impl<'a> From<&'a Refresh> for Serializable { - fn from(refresh: &Refresh) -> Self { - Serializable { - refresh_token: refresh.refresh_token.clone(), - expires: refresh.expires.timestamp(), - } - } -} - -impl Into for Serializable { - fn into(self) -> Refresh { - Refresh { - refresh_token: self.refresh_token, - expires: UTC.timestamp(self.expires, 0), - } - } -} - -impl Encodable for Refresh { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - Serializable::from(self).encode(s) - } -} - -impl Decodable for Refresh { - fn decode(d: &mut D) -> Result { - Serializable::decode(d).map(Into::into) - } -} - -#[cfg(feature = "serde")] -mod serde { - use chrono::{UTC, TimeZone}; - use serde::{Serialize, Serializer, Deserialize, Deserializer}; - use serde::{ser, de}; - - use super::Refresh; - - impl Serialize for Refresh { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> { - serializer.serialize_struct("Refresh", SerVisitor(self, 0)) - } - } - - struct SerVisitor<'a>(&'a Refresh, u8); - impl<'a> ser::MapVisitor for SerVisitor<'a> { - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> { - self.1 += 1; - match self.1 { - 1 => serializer.serialize_struct_elt("refresh_token", &self.0.refresh_token).map(Some), - 2 => serializer.serialize_struct_elt("expires", &self.0.expires.timestamp()).map(Some), - _ => Ok(None), - } - } - - fn len(&self) -> Option { Some(2) } - } - - impl Deserialize for Refresh { - fn deserialize(deserializer: &mut D) -> Result { - static FIELDS: &'static [&'static str] = &["refresh_token", "expires"]; - deserializer.deserialize_struct("Refresh", FIELDS, DeVisitor) - } - } - - struct DeVisitor; - impl de::Visitor for DeVisitor { - type Value = Refresh; - - fn visit_map(&mut self, mut visitor: V) -> Result { - let mut refresh_token = None; - let mut expires = None; - - loop { - match try!(visitor.visit_key()) { - Some(Field::RefreshToken) => refresh_token = Some(try!(visitor.visit_value())), - Some(Field::Expires) => expires = Some(try!(visitor.visit_value())), - None => break, - } - } - - let refresh_token = match refresh_token { - Some(s) => s, - None => return visitor.missing_field("refresh_token"), - }; - let expires = match expires { - Some(i) => UTC.timestamp(i, 0), - None => return visitor.missing_field("expires"), - }; - - try!(visitor.end()); - - Ok(Refresh { - refresh_token: refresh_token, - expires: expires, - }) - } - } - - enum Field { - RefreshToken, - Expires, - } - - impl Deserialize for Field { - fn deserialize(deserializer: &mut D) -> Result { - deserializer.deserialize(FieldVisitor) - } - } - - struct FieldVisitor; - impl de::Visitor for FieldVisitor { - type Value = Field; - - fn visit_str(&mut self, value: &str) -> Result { - match value { - "refresh_token" => Ok(Field::RefreshToken), - "expires" => Ok(Field::Expires), - _ => Err(de::Error::custom("expected refresh_token or expires")), - } - } - } -} - #[cfg(test)] mod tests { - use chrono::{UTC, Duration, Timelike}; - use rustc_serialize::json::{self, Json}; + use chrono::{UTC, Duration}; use client::response::FromResponse; use super::Refresh; #[test] fn from_response() { - let json = Json::from_str(r#"{"refresh_token":"aaaaaaaa","expires_in":3600}"#).unwrap(); + let json = r#"{"refresh_token":"aaaaaaaa","expires_in":3600}"#.parse().unwrap(); let refresh = Refresh::from_response(&json).unwrap(); assert_eq!("aaaaaaaa", refresh.refresh_token); assert!(refresh.expires > UTC::now()); @@ -204,7 +79,7 @@ mod tests { #[test] fn from_response_inherit() { - let json = Json::from_str(r#"{"expires_in":3600}"#).unwrap(); + let json = r#"{"expires_in":3600}"#.parse().unwrap(); let prev = Refresh { refresh_token: String::from("aaaaaaaa"), expires: UTC::now(), @@ -214,29 +89,4 @@ mod tests { assert!(refresh.expires > UTC::now()); assert!(refresh.expires <= UTC::now() + Duration::seconds(3600)); } - - #[test] - fn encode_decode() { - let refresh = Refresh { - refresh_token: String::from("foo"), - expires: UTC::now().with_nanosecond(0).unwrap(), - }; - let json = json::encode(&refresh).unwrap(); - let decoded = json::decode(&json).unwrap(); - assert_eq!(refresh, decoded); - } - - #[cfg(feature = "serde")] - #[test] - fn serialize_deserialize() { - use serde_json; - - let original = Refresh { - refresh_token: String::from("foo"), - expires: UTC::now().with_nanosecond(0).unwrap(), - }; - let serialized = serde_json::to_value(&original); - let deserialized = serde_json::from_value(serialized).unwrap(); - assert_eq!(original, deserialized); - } } diff --git a/src/token/statik.rs b/src/token/statik.rs index 7c6f162..64e9a98 100644 --- a/src/token/statik.rs +++ b/src/token/statik.rs @@ -1,10 +1,10 @@ -use rustc_serialize::json::Json; +use serde_json::Value; use super::Lifetime; -use client::response::{FromResponse, ParseError, JsonHelper}; +use client::response::{FromResponse, ParseError}; /// A static, non-expiring token. -#[derive(Debug, Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct Static; impl Lifetime for Static { @@ -12,66 +12,32 @@ impl Lifetime for Static { } impl FromResponse for Static { - fn from_response(json: &Json) -> Result { - let obj = try!(JsonHelper(json).as_object()); - if obj.0.contains_key("expires_in") { + fn from_response(json: &Value) -> Result { + let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?; + if obj.contains_key("expires_in") { return Err(ParseError::UnexpectedField("expires_in")); } Ok(Static) } } -#[cfg(feature = "serde")] -mod serde { - use serde::{Serialize, Serializer, Deserialize, Deserializer}; - use serde::de::impls::UnitVisitor; - - use super::Static; - - impl Serialize for Static { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> { - serializer.serialize_unit_struct("Static") - } - } - - impl Deserialize for Static { - fn deserialize(deserializer: &mut D) -> Result { - deserializer.deserialize_unit_struct("Static", UnitVisitor) - .and(Ok(Static)) - } - } -} - #[cfg(test)] mod tests { - use rustc_serialize::json::Json; - use client::response::{FromResponse, ParseError}; use super::Static; #[test] fn from_response() { - let json = Json::from_str("{}").unwrap(); + let json = "{}".parse().unwrap(); assert_eq!(Static, Static::from_response(&json).unwrap()); } #[test] fn from_response_with_expires_in() { - let json = Json::from_str(r#"{"expires_in":3600}"#).unwrap(); + let json = r#"{"expires_in":3600}"#.parse().unwrap(); assert_eq!( ParseError::UnexpectedField("expires_in"), Static::from_response(&json).unwrap_err() ); } - - #[cfg(feature = "serde")] - #[test] - fn serialize_deserialize() { - use serde_json; - - let original = Static; - let serialized = serde_json::to_value(&original); - let deserialized = serde_json::from_value(serialized).unwrap(); - assert_eq!(original, deserialized); - } }