use serde::de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor};
use serde::de::impls::{VecVisitor};
use super::{Id, Params, Version, Value};
#[derive(Debug, PartialEq, Deserialize)]
pub struct MethodCall {
pub jsonrpc: Version,
pub method: String,
pub params: Option<Params>,
pub id: Id,
}
#[derive(Debug, PartialEq, Deserialize)]
pub struct Notification {
pub jsonrpc: Version,
pub method: String,
pub params: Option<Params>
}
#[derive(Debug, PartialEq)]
pub enum Call {
MethodCall(MethodCall),
Notification(Notification),
Invalid(Value)
}
impl Deserialize for Call {
fn deserialize<D>(deserializer: &mut D) -> Result<Call, D::Error>
where D: Deserializer {
ok!(MethodCall::deserialize(deserializer).map(Call::MethodCall));
ok!(Notification::deserialize(deserializer).map(Call::Notification));
Value::deserialize(deserializer).map(Call::Invalid)
}
}
#[derive(Debug, PartialEq)]
pub enum Request {
Single(Call),
Batch(Vec<Call>)
}
impl Deserialize for Request {
fn deserialize<D>(deserializer: &mut D) -> Result<Request, D::Error>
where D: Deserializer {
ok!(Call::deserialize(deserializer).map(Request::Single));
deserializer.visit(BatchVisitor)
}
}
struct BatchVisitor;
impl Visitor for BatchVisitor {
type Value = Request;
fn visit_seq<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor {
VecVisitor::new().visit_seq(visitor).map(Request::Batch)
}
}
#[test]
fn notification_deserialize() {
use serde_json;
use serde_json::Value;
let s = r#"{"jsonrpc": "2.0", "method": "update", "params": [1,2]}"#;
let deserialized: Notification = serde_json::from_str(s).unwrap();
assert_eq!(deserialized, Notification {
jsonrpc: Version::V2,
method: "update".to_string(),
params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)]))
});
let s = r#"{"jsonrpc": "2.0", "method": "foobar"}"#;
let deserialized: Notification = serde_json::from_str(s).unwrap();
assert_eq!(deserialized, Notification {
jsonrpc: Version::V2,
method: "foobar".to_string(),
params: None
});
let s = r#"{"jsonrpc": "2.0", "method": "update", "params": [1,2], "id": 1}"#;
let deserialized: Result<Notification, _> = serde_json::from_str(s);
assert!(deserialized.is_err())
}