Use serde for json serialization.

This commit is contained in:
Paul Lietar 2016-07-06 02:29:38 +01:00
parent e688914082
commit 24471eef9b
8 changed files with 116 additions and 37 deletions

63
Cargo.lock generated
View file

@ -26,6 +26,10 @@ dependencies = [
"rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.7.12 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.12 (registry+https://github.com/rust-lang/crates.io-index)",
"shannon 0.1.1 (git+https://github.com/plietar/rust-shannon)", "shannon 0.1.1 (git+https://github.com/plietar/rust-shannon)",
"tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
@ -209,6 +213,11 @@ dependencies = [
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "itoa"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "json_macros" name = "json_macros"
version = "0.3.1" version = "0.3.1"
@ -530,6 +539,14 @@ dependencies = [
"syntex_syntax 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "quasi_macros"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quasi_codegen 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "quine-mc_cluskey" name = "quine-mc_cluskey"
version = "0.2.2" version = "0.2.2"
@ -609,6 +626,52 @@ dependencies = [
"nom 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "nom 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "serde"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_codegen"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aster 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi_codegen 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen_internals 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_codegen_internals"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syntex_errors 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_macros"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_codegen 0.7.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "shannon" name = "shannon"
version = "0.1.1" version = "0.1.1"

View file

@ -31,6 +31,9 @@ rand = "~0.3.13"
rpassword = "~0.2.2" rpassword = "~0.2.2"
rust-crypto = "~0.2.34" rust-crypto = "~0.2.34"
rustc-serialize = "~0.3.16" rustc-serialize = "~0.3.16"
serde = "0.7"
serde_json = "0.7"
serde_macros = { version = "0.7", optional = true }
tempfile = "~2.1.3" tempfile = "~2.1.3"
time = "~0.1.34" time = "~0.1.34"
url = "~0.5.0" url = "~0.5.0"
@ -57,10 +60,12 @@ openssl = { version = "0.7", optional = true }
vergen = "~0.1.0" vergen = "~0.1.0"
protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" } protobuf_macros = { git = "https://github.com/plietar/rust-protobuf-macros" }
json_macros = { git = "https://github.com/plietar/json_macros" } json_macros = { git = "https://github.com/plietar/json_macros" }
serde_codegen = { version = "0.7", optional = true }
[features] [features]
discovery = ["dns-sd"] discovery = ["dns-sd"]
with-syntex = ["protobuf_macros/with-syntex", "json_macros/with-syntex"] with-syntex = ["serde_codegen", "protobuf_macros/with-syntex", "json_macros/with-syntex"]
nightly = ["serde_macros"]
with-tremor = ["tremor"] with-tremor = ["tremor"]
facebook = ["hyper/ssl", "openssl"] facebook = ["hyper/ssl", "openssl"]
portaudio-backend = ["portaudio"] portaudio-backend = ["portaudio"]

View file

@ -81,7 +81,7 @@ The following backends are currently available :
## Development ## Development
When developing *librespot*, it is preferable to use Rust nightly, and build it using the following : When developing *librespot*, it is preferable to use Rust nightly, and build it using the following :
```shell ```shell
cargo build --no-default-features --features portaudio-backend cargo build --no-default-features --features "nightly portaudio-backend"
``` ```
This produces better compilation error messages than with the default configuration. This produces better compilation error messages than with the default configuration.

View file

@ -4,6 +4,7 @@ extern crate vergen;
fn codegen() { fn codegen() {
extern crate json_macros; extern crate json_macros;
extern crate protobuf_macros; extern crate protobuf_macros;
extern crate serde_codegen;
use std::env; use std::env;
use std::path::PathBuf; use std::path::PathBuf;
@ -11,7 +12,8 @@ fn codegen() {
let out = PathBuf::from(env::var("OUT_DIR").unwrap()); let out = PathBuf::from(env::var("OUT_DIR").unwrap());
json_macros::expand("src/lib.in.rs", &out.join("lib.tmp0.rs")).unwrap(); json_macros::expand("src/lib.in.rs", &out.join("lib.tmp0.rs")).unwrap();
protobuf_macros::expand(&out.join("lib.tmp0.rs"), &out.join("lib.rs")).unwrap(); serde_codegen::expand(&out.join("lib.tmp0.rs"), &out.join("lib.tmp1.rs")).unwrap();
protobuf_macros::expand(&out.join("lib.tmp1.rs"), &out.join("lib.rs")).unwrap();
} }
#[cfg(not(feature = "with-syntex"))] #[cfg(not(feature = "with-syntex"))]

View file

@ -2,9 +2,9 @@ const APRESOLVE_ENDPOINT : &'static str = "http://apresolve.spotify.com/";
use hyper; use hyper;
use std::io::Read; use std::io::Read;
use rustc_serialize::json; use serde_json;
#[derive(RustcDecodable)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct APResolveData { pub struct APResolveData {
ap_list: Vec<String> ap_list: Vec<String>
} }
@ -16,7 +16,7 @@ pub fn apresolve() -> Result<Vec<String>, ()> {
let mut data = String::new(); let mut data = String::new();
response.read_to_string(&mut data).unwrap(); response.read_to_string(&mut data).unwrap();
let data : APResolveData = json::decode(&data).unwrap(); let data : APResolveData = serde_json::from_str(&data).unwrap();
Ok(data.ap_list) Ok(data.ap_list)
} }

View file

@ -5,7 +5,7 @@ use hyper::server::Response;
use hyper::uri::RequestUri; use hyper::uri::RequestUri;
use hyper::header::AccessControlAllowOrigin; use hyper::header::AccessControlAllowOrigin;
use rand::{self, Rng}; use rand::{self, Rng};
use rustc_serialize::json; use serde_json;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::io::Read; use std::io::Read;
use std::sync::{mpsc, Mutex}; use std::sync::{mpsc, Mutex};
@ -63,7 +63,7 @@ fn facebook_get_me_id(token: &str) -> Result<String, ()> {
let mut body = String::new(); let mut body = String::new();
response.read_to_string(&mut body).unwrap(); response.read_to_string(&mut body).unwrap();
let mut result : BTreeMap<String, String> = json::decode(&body).unwrap(); let mut result : BTreeMap<String, String> = serde_json::from_str(&body).unwrap();
Ok(result.remove("id").unwrap()) Ok(result.remove("id").unwrap())
} }

View file

@ -6,27 +6,27 @@ use crypto::hmac::Hmac;
use crypto::pbkdf2::pbkdf2; use crypto::pbkdf2::pbkdf2;
use crypto::sha1::Sha1; use crypto::sha1::Sha1;
use protobuf::ProtobufEnum; use protobuf::ProtobufEnum;
use serde;
use serde_json;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
use rustc_serialize::base64::{self, FromBase64, ToBase64}; use rustc_serialize::base64::{self, FromBase64, ToBase64};
use rustc_serialize::json;
use protocol::authentication::AuthenticationType; use protocol::authentication::AuthenticationType;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[derive(Serialize, Deserialize)]
pub struct Credentials { pub struct Credentials {
pub username: String, pub username: String,
pub auth_type: AuthenticationType,
pub auth_data: Vec<u8>,
}
#[derive(Debug, Clone)] #[serde(serialize_with="serialize_protobuf_enum")]
#[derive(RustcDecodable, RustcEncodable)] #[serde(deserialize_with="deserialize_protobuf_enum")]
struct StoredCredentials { pub auth_type: AuthenticationType,
pub username: String,
pub auth_type: i32, #[serde(serialize_with="serialize_base64")]
pub auth_data: String, #[serde(deserialize_with="deserialize_base64")]
pub auth_data: Vec<u8>,
} }
impl Credentials { impl Credentials {
@ -124,7 +124,7 @@ impl Credentials {
let mut contents = String::new(); let mut contents = String::new();
reader.read_to_string(&mut contents).unwrap(); reader.read_to_string(&mut contents).unwrap();
json::decode::<StoredCredentials>(&contents).unwrap().into() serde_json::from_str(&contents).unwrap()
} }
pub fn from_file<P: AsRef<Path>>(path: P) -> Option<Credentials> { pub fn from_file<P: AsRef<Path>>(path: P) -> Option<Credentials> {
@ -132,7 +132,7 @@ impl Credentials {
} }
pub fn save_to_writer<W: Write>(&self, writer: &mut W) { pub fn save_to_writer<W: Write>(&self, writer: &mut W) {
let contents = json::encode::<StoredCredentials>(&self.clone().into()).unwrap(); let contents = serde_json::to_string(&self.clone()).unwrap();
writer.write_all(contents.as_bytes()).unwrap(); writer.write_all(contents.as_bytes()).unwrap();
} }
@ -142,24 +142,30 @@ impl Credentials {
} }
} }
impl From<Credentials> for StoredCredentials { fn serialize_protobuf_enum<T, S>(v: &T, ser: &mut S) -> Result<(), S::Error>
fn from(credentials: Credentials) -> StoredCredentials { where T: ProtobufEnum, S: serde::Serializer {
StoredCredentials {
username: credentials.username, serde::Serialize::serialize(&v.value(), ser)
auth_type: credentials.auth_type.value(),
auth_data: credentials.auth_data.to_base64(base64::STANDARD),
}
}
} }
impl From<StoredCredentials> for Credentials { fn deserialize_protobuf_enum<T, D>(de: &mut D) -> Result<T, D::Error>
fn from(credentials: StoredCredentials) -> Credentials { where T: ProtobufEnum, D: serde::Deserializer {
Credentials {
username: credentials.username, let v : i32 = try!(serde::Deserialize::deserialize(de));
auth_type: AuthenticationType::from_i32(credentials.auth_type).unwrap(), T::from_i32(v).ok_or(serde::Error::invalid_value("Invalid enum value"))
auth_data: credentials.auth_data.from_base64().unwrap(),
} }
fn serialize_base64<T, S>(v: &T, ser: &mut S) -> Result<(), S::Error>
where T: AsRef<[u8]>, S: serde::Serializer {
serde::Serialize::serialize(&v.as_ref().to_base64(base64::STANDARD), ser)
} }
fn deserialize_base64<D>(de: &mut D) -> Result<Vec<u8>, D::Error>
where D: serde::Deserializer {
let v : String = try!(serde::Deserialize::deserialize(de));
v.from_base64().map_err(|e| serde::Error::custom(e.to_string()))
} }
#[cfg(feature = "discovery")] #[cfg(feature = "discovery")]

View file

@ -1,8 +1,9 @@
#![crate_name = "librespot"] #![crate_name = "librespot"]
#![cfg_attr(not(feature = "with-syntex"), feature(plugin))] #![cfg_attr(not(feature = "with-syntex"), feature(plugin, custom_derive))]
#![cfg_attr(not(feature = "with-syntex"), plugin(protobuf_macros))] #![cfg_attr(not(feature = "with-syntex"), plugin(protobuf_macros))]
#![cfg_attr(not(feature = "with-syntex"), plugin(json_macros))] #![cfg_attr(not(feature = "with-syntex"), plugin(json_macros))]
#![cfg_attr(not(feature = "with-syntex"), plugin(serde_macros))]
#![cfg_attr(feature="clippy", feature(plugin))] #![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))] #![cfg_attr(feature="clippy", plugin(clippy))]
@ -24,6 +25,8 @@ extern crate shannon;
extern crate rand; extern crate rand;
extern crate rpassword; extern crate rpassword;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde;
extern crate serde_json;
extern crate time; extern crate time;
extern crate tempfile; extern crate tempfile;
extern crate url; extern crate url;