diff --git a/core/Cargo.toml b/core/Cargo.toml index 8ae04bf53..4524a46bd 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -7,23 +7,17 @@ name = "jsonrpc-core" version = "5.1.0" authors = ["debris "] keywords = ["jsonrpc", "json-rpc", "json", "rpc", "serde"] -build = "build.rs" documentation = "https://ethcore.github.io/jsonrpc/jsonrpc_core/index.html" [dependencies] log = "0.3" futures = "0.1.6" # always carefully check serde versions before an update -serde = "0.8" -serde_json = "0.8" -serde_macros = { version = "0.8", optional = true } +serde = "0.9" +serde_json = "0.9" +serde_derive = "0.9" # Optional dependencies for reactor support tokio-core = { version = "0.1", optional = true} -[build-dependencies] -serde_codegen = { version = "0.8", optional = true } - [features] -default = ["serde_codegen"] -nightly = ["serde_macros"] reactor = ["tokio-core"] diff --git a/core/build.rs b/core/build.rs deleted file mode 100644 index 6e2076eca..000000000 --- a/core/build.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[cfg(not(feature = "serde_macros"))] -mod inner { - extern crate serde_codegen; - - use std::env; - use std::path::Path; - - pub fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - - let src = Path::new("src/types/mod.rs.in"); - let dst = Path::new(&out_dir).join("types.rs"); - - serde_codegen::expand(&src, &dst).unwrap(); - } -} - -#[cfg(feature = "serde_macros")] -mod inner { - pub fn main() {} -} - -fn main() { - inner::main(); -} diff --git a/core/src/lib.rs b/core/src/lib.rs index eade301e9..2ee1489f9 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -22,10 +22,9 @@ //! ``` #![warn(missing_docs)] -#![cfg_attr(feature="nightly", feature(custom_derive, plugin))] -#![cfg_attr(feature="nightly", plugin(serde_macros))] #[macro_use] extern crate log; +#[macro_use] extern crate serde_derive; extern crate serde; extern crate serde_json; diff --git a/core/src/types/error.rs b/core/src/types/error.rs index 521c03b95..943a314f0 100644 --- a/core/src/types/error.rs +++ b/core/src/types/error.rs @@ -49,9 +49,9 @@ impl ErrorCode { } impl Deserialize for ErrorCode { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { - let v = try!(Value::deserialize(deserializer)); + let v: Value = try!(Deserialize::deserialize(deserializer)); match v.as_i64() { Some(-32700) => Ok(ErrorCode::ParseError), Some(-32600) => Ok(ErrorCode::InvalidRequest), @@ -66,7 +66,7 @@ impl Deserialize for ErrorCode { } impl Serialize for ErrorCode { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { serializer.serialize_i64(self.code()) } diff --git a/core/src/types/id.rs b/core/src/types/id.rs index 3fe75067e..75d272a29 100644 --- a/core/src/types/id.rs +++ b/core/src/types/id.rs @@ -1,6 +1,8 @@ //! jsonrpc id field -use serde::{Serialize, Serializer, Deserialize, Deserializer, Error}; -use serde::de::Visitor; +use std::fmt; + +use serde::{Serialize, Serializer, Deserialize, Deserializer}; +use serde::de::{self, Visitor}; /// Request Id #[derive(Debug, PartialEq, Clone)] @@ -14,7 +16,7 @@ pub enum Id { } impl Serialize for Id { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match *self { Id::Null => serializer.serialize_unit(), @@ -25,7 +27,7 @@ impl Serialize for Id { } impl Deserialize for Id { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { deserializer.deserialize(IdVisitor) } @@ -36,19 +38,23 @@ struct IdVisitor; impl Visitor for IdVisitor { type Value = Id; - fn visit_unit(&mut self) -> Result where E: Error { + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a unit, integer or string") + } + + fn visit_unit(self) -> Result where E: de::Error { Ok(Id::Null) } - fn visit_u64(&mut self, value: u64) -> Result where E: Error { + fn visit_u64(self, value: u64) -> Result where E: de::Error { Ok(Id::Num(value)) } - fn visit_str(&mut self, value: &str) -> Result where E: Error { + fn visit_str(self, value: &str) -> Result where E: de::Error { self.visit_string(value.to_owned()) } - fn visit_string(&mut self, value: String) -> Result where E: Error { + fn visit_string(self, value: String) -> Result where E: de::Error { value.parse::().map(Id::Num).or(Ok(Id::Str(value))) } } diff --git a/core/src/types/mod.rs b/core/src/types/mod.rs index 0e1b33c2c..d1c6f5146 100644 --- a/core/src/types/mod.rs +++ b/core/src/types/mod.rs @@ -1,7 +1,16 @@ -//! JSON-RPC types +pub mod error; +pub mod id; +pub mod params; +pub mod request; +pub mod response; +pub mod version; -#[cfg(feature = "serde_macros")] -include!("mod.rs.in"); +pub use serde_json::Value; +pub use serde_json::value::to_value; -#[cfg(not(feature = "serde_macros"))] -include!(concat!(env!("OUT_DIR"), "/types.rs")); +pub use self::error::{ErrorCode, Error}; +pub use self::id::Id; +pub use self::params::Params; +pub use self::request::{Request, Call, MethodCall, Notification}; +pub use self::response::{Output, Response, Success, Failure}; +pub use self::version::Version; diff --git a/core/src/types/mod.rs.in b/core/src/types/mod.rs.in deleted file mode 100644 index d1c6f5146..000000000 --- a/core/src/types/mod.rs.in +++ /dev/null @@ -1,16 +0,0 @@ -pub mod error; -pub mod id; -pub mod params; -pub mod request; -pub mod response; -pub mod version; - -pub use serde_json::Value; -pub use serde_json::value::to_value; - -pub use self::error::{ErrorCode, Error}; -pub use self::id::Id; -pub use self::params::Params; -pub use self::request::{Request, Call, MethodCall, Notification}; -pub use self::response::{Output, Response, Success, Failure}; -pub use self::version::Version; diff --git a/core/src/types/params.rs b/core/src/types/params.rs index 975cc8dc7..28e20645c 100644 --- a/core/src/types/params.rs +++ b/core/src/types/params.rs @@ -1,9 +1,10 @@ //! jsonrpc params field -use std::collections::BTreeMap; +use std::fmt; use serde::{Serialize, Serializer, Deserialize, Deserializer}; use serde::de::{Visitor, SeqVisitor, MapVisitor}; -use serde::de::impls::{VecVisitor, BTreeMapVisitor}; +use serde::de::impls::{VecVisitor}; +use serde_json; use serde_json::value::from_value; use super::{Value, Error}; @@ -14,7 +15,7 @@ pub enum Params { /// Array of values Array(Vec), /// Map of values - Map(BTreeMap), + Map(serde_json::Map), /// No parameters None } @@ -33,7 +34,7 @@ impl Params { } impl Serialize for Params { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match *self { Params::Array(ref vec) => vec.serialize(serializer), @@ -46,7 +47,7 @@ impl Serialize for Params { struct ParamsVisitor; impl Deserialize for Params { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { deserializer.deserialize(ParamsVisitor) } @@ -55,7 +56,11 @@ impl Deserialize for Params { impl Visitor for ParamsVisitor { type Value = Params; - fn visit_seq(&mut self, visitor: V) -> Result + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map or sequence") + } + + fn visit_seq(self, visitor: V) -> Result where V: SeqVisitor { VecVisitor::new().visit_seq(visitor).and_then(|vec| match vec.is_empty() { true => Ok(Params::None), @@ -63,12 +68,15 @@ impl Visitor for ParamsVisitor { }) } - fn visit_map(&mut self, visitor: V) -> Result + fn visit_map(self, mut visitor: V) -> Result where V: MapVisitor { - BTreeMapVisitor::new().visit_map(visitor).and_then(|map| match map.is_empty() { - true => Ok(Params::None), - false => Ok(Params::Map(map)) - }) + let mut values = serde_json::Map::with_capacity(visitor.size_hint().0); + + while let Some((key, value)) = visitor.visit()? { + values.insert(key, value); + } + + Ok(if values.is_empty() { Params::None } else { Params::Map(values) }) } } @@ -76,16 +84,14 @@ impl Visitor for ParamsVisitor { fn params_deserialization() { use serde_json; - use std::collections::BTreeMap; - let s = r#"[null, true, -1, 4, 2.3, "hello", [0], {"key": "value"}]"#; let deserialized: Params = serde_json::from_str(s).unwrap(); - let mut map = BTreeMap::new(); + let mut map = serde_json::Map::new(); map.insert("key".to_string(), Value::String("value".to_string())); assert_eq!(Params::Array(vec![ - Value::Null, Value::Bool(true), Value::I64(-1), Value::U64(4), - Value::F64(2.3), Value::String("hello".to_string()), - Value::Array(vec![Value::U64(0)]), Value::Object(map)]), deserialized); + Value::Null, Value::Bool(true), Value::from(-1), Value::from(4), + Value::from(2.3), Value::String("hello".to_string()), + Value::Array(vec![Value::from(0)]), Value::Object(map)]), deserialized); } diff --git a/core/src/types/request.rs b/core/src/types/request.rs index c72bee814..074f1eac0 100644 --- a/core/src/types/request.rs +++ b/core/src/types/request.rs @@ -48,7 +48,7 @@ pub enum Call { } impl Serialize for Call { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match *self { Call::MethodCall(ref m) => m.serialize(serializer), @@ -59,13 +59,13 @@ impl Serialize for Call { } impl Deserialize for Call { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { - let v = try!(Value::deserialize(deserializer)); + let v: Value = try!(Deserialize::deserialize(deserializer)); from_value(v.clone()).map(Call::Notification) .or_else(|_: JsonError| from_value(v.clone()).map(Call::MethodCall)) .or_else(|_: JsonError| { - let id = v.find("id") + let id = v.get("id") .and_then(|id| from_value(id.clone()).ok()) .unwrap_or(Id::Null); Ok(Call::Invalid(id)) @@ -84,7 +84,7 @@ pub enum Request { } impl Serialize for Request { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match *self { Request::Single(ref call) => call.serialize(serializer), @@ -94,9 +94,9 @@ impl Serialize for Request { } impl Deserialize for Request { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { - let v = try!(Value::deserialize(deserializer)); + let v: Value = try!(Deserialize::deserialize(deserializer)); from_value(v.clone()).map(Request::Batch) .or_else(|_| from_value(v).map(Request::Single)) .map_err(|_| D::Error::custom("")) // unreachable, but types must match @@ -111,7 +111,7 @@ fn method_call_serialize() { let m = MethodCall { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)])), + params: Some(Params::Array(vec![Value::from(1), Value::from(2)])), id: Id::Num(1) }; @@ -127,7 +127,7 @@ fn notification_serialize() { let n = Notification { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)])) + params: Some(Params::Array(vec![Value::from(1), Value::from(2)])) }; let serialized = serde_json::to_string(&n).unwrap(); @@ -142,7 +142,7 @@ fn call_serialize() { let n = Call::Notification(Notification { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1)])) + params: Some(Params::Array(vec![Value::from(1)])) }); let serialized = serde_json::to_string(&n).unwrap(); @@ -157,13 +157,13 @@ fn request_serialize_batch() { Call::MethodCall(MethodCall { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)])), + params: Some(Params::Array(vec![Value::from(1), Value::from(2)])), id: Id::Num(1) }), Call::Notification(Notification { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1)])) + params: Some(Params::Array(vec![Value::from(1)])) }) ]); @@ -183,7 +183,7 @@ fn notification_deserialize() { assert_eq!(deserialized, Notification { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)])) + params: Some(Params::Array(vec![Value::from(1), Value::from(2)])) }); let s = r#"{"jsonrpc": "2.0", "method": "foobar"}"#; @@ -209,7 +209,7 @@ fn call_deserialize() { assert_eq!(deserialized, Call::Notification(Notification { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1)])) + params: Some(Params::Array(vec![Value::from(1)])) })); let s = r#"{"jsonrpc": "2.0", "method": "update", "params": [1], "id": 1}"#; @@ -217,7 +217,7 @@ fn call_deserialize() { assert_eq!(deserialized, Call::MethodCall(MethodCall { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1)])), + params: Some(Params::Array(vec![Value::from(1)])), id: Id::Num(1) })); } @@ -233,13 +233,13 @@ fn request_deserialize_batch() { Call::MethodCall(MethodCall { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)])), + params: Some(Params::Array(vec![Value::from(1), Value::from(2)])), id: Id::Num(1) }), Call::Notification(Notification { jsonrpc: Some(Version::V2), method: "update".to_owned(), - params: Some(Params::Array(vec![Value::U64(1)])) + params: Some(Params::Array(vec![Value::from(1)])) }) ])) } diff --git a/core/src/types/response.rs b/core/src/types/response.rs index ad842b5c4..beddeb515 100644 --- a/core/src/types/response.rs +++ b/core/src/types/response.rs @@ -63,9 +63,9 @@ impl Output { } impl Deserialize for Output { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { - let v = try!(Value::deserialize(deserializer)); + let v: Value = try!(Deserialize::deserialize(deserializer)); from_value(v.clone()).map(Output::Failure) .or_else(|_| from_value(v).map(Output::Success)) .map_err(|_| D::Error::custom("")) // types must match @@ -73,7 +73,7 @@ impl Deserialize for Output { } impl Serialize for Output { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match *self { Output::Success(ref s) => s.serialize(serializer), @@ -92,9 +92,9 @@ pub enum Response { } impl Deserialize for Response { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { - let v = try!(Value::deserialize(deserializer)); + let v: Value = try!(Deserialize::deserialize(deserializer)); from_value(v.clone()).map(Response::Batch) .or_else(|_| from_value(v).map(Response::Single)) .map_err(|_| D::Error::custom("")) // types must match @@ -102,7 +102,7 @@ impl Deserialize for Response { } impl Serialize for Response { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match *self { Response::Single(ref o) => o.serialize(serializer), @@ -141,7 +141,7 @@ fn success_output_serialize() { let so = Output::Success(Success { jsonrpc: Some(Version::V2), - result: Value::U64(1), + result: Value::from(1), id: Id::Num(1) }); @@ -159,7 +159,7 @@ fn success_output_deserialize() { let deserialized: Output = serde_json::from_str(dso).unwrap(); assert_eq!(deserialized, Output::Success(Success { jsonrpc: Some(Version::V2), - result: Value::U64(1), + result: Value::from(1), id: Id::Num(1) })); } @@ -202,7 +202,7 @@ fn single_response_deserialize() { let deserialized: Response = serde_json::from_str(dsr).unwrap(); assert_eq!(deserialized, Response::Single(Output::Success(Success { jsonrpc: Some(Version::V2), - result: Value::U64(1), + result: Value::from(1), id: Id::Num(1) }))); } @@ -218,7 +218,7 @@ fn batch_response_deserialize() { assert_eq!(deserialized, Response::Batch(vec![ Output::Success(Success { jsonrpc: Some(Version::V2), - result: Value::U64(1), + result: Value::from(1), id: Id::Num(1) }), Output::Failure(Failure { diff --git a/core/src/types/version.rs b/core/src/types/version.rs index 9f8d5108b..bff1e0c50 100644 --- a/core/src/types/version.rs +++ b/core/src/types/version.rs @@ -1,6 +1,8 @@ //! jsonrpc version field -use serde::{Serialize, Serializer, Deserialize, Deserializer, Error}; -use serde::de::Visitor; +use serde::{Serialize, Serializer, Deserialize, Deserializer}; +use serde::de::{self, Visitor}; + +use std::fmt; /// Protocol Version #[derive(Debug, PartialEq, Clone, Copy)] @@ -10,7 +12,7 @@ pub enum Version { } impl Serialize for Version { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + fn serialize(&self, serializer: S) -> Result where S: Serializer { match self { &Version::V2 => serializer.serialize_str("2.0") @@ -19,7 +21,7 @@ impl Serialize for Version { } impl Deserialize for Version { - fn deserialize(deserializer: &mut D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer { deserializer.deserialize(VersionVisitor) } @@ -30,15 +32,15 @@ struct VersionVisitor; impl Visitor for VersionVisitor { type Value = Version; - fn visit_str(&mut self, value: &str) -> Result where E: Error { + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, value: &str) -> Result where E: de::Error { match value { "2.0" => Ok(Version::V2), - _ => Err(Error::custom("invalid version")) + _ => Err(de::Error::custom("invalid version")) } } - - fn visit_string(&mut self, value: String) -> Result where E: Error { - self.visit_str(value.as_ref()) - } } diff --git a/macros/Cargo.toml b/macros/Cargo.toml index a22ad9903..dc0fd6c38 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -10,5 +10,5 @@ keywords = ["jsonrpc", "json-rpc", "json", "rpc", "macros"] documentation = "https://ethcore.github.io/jsonrpc/jsonrpc_macros/index.html" [dependencies] -serde = "0.8" +serde = "0.9" jsonrpc-core = { version = "5.1", path = "../core" } diff --git a/macros/src/auto_args.rs b/macros/src/auto_args.rs index 608ef7fbc..258c017b7 100644 --- a/macros/src/auto_args.rs +++ b/macros/src/auto_args.rs @@ -4,11 +4,15 @@ ///! Automatically serialize and deserialize parameters around a strongly-typed function. -use jsonrpc_core::{Error, Params, Value, to_value, Metadata}; +use jsonrpc_core::{self, Error, Params, Value, Metadata}; use jsonrpc_core::futures::{self, BoxFuture, Future}; use serde::{Serialize, Deserialize}; use util::{invalid_params, expect_no_params}; +fn to_value(value: T) -> Value where T: Serialize { + jsonrpc_core::to_value(value).unwrap() +} + /// Auto-generates an RPC trait from trait definition. /// /// This just copies out all the methods, docs, and adds another diff --git a/tcp/Cargo.toml b/tcp/Cargo.toml index c536ad945..9d444dab8 100644 --- a/tcp/Cargo.toml +++ b/tcp/Cargo.toml @@ -11,7 +11,7 @@ jsonrpc-core = { version = "5.1", path = "../core" } log = "0.3" env_logger = "0.3" lazy_static = "0.2" -serde_json = "0.8" +serde_json = "0.9" rand = "0.3" tokio-core = "0.1" tokio-service = "0.1"