use serde::de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor};
use super::{Id, Params, Version, Value};
use super::peek::*;
#[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
}
impl Deserialize for Call {
fn deserialize<D>(deserializer: &mut D) -> Result<Call, D::Error>
where D: Deserializer {
Notification::peek(deserializer).map(Call::Notification)
.or_else(|_| MethodCall::peek(deserializer).map(Call::MethodCall))
.or_else(|_| 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 {
<Vec<Call> as Peek>::peek(deserializer).map(Request::Batch)
.or_else(|_| Call::deserialize(deserializer).map(Request::Single))
}
}
#[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())
}
#[test]
fn call_deserialize_batch() {
use serde_json;
let s = r#"[1, {"jsonrpc": "2.0", "method": "update", "params": [1,2], "id": 1},{"jsonrpc": "2.0", "method": "update", "params": [1]}]"#;
let deserialized: Request = serde_json::from_str(s).unwrap();
assert_eq!(deserialized, Request::Batch(vec![
Call::Invalid,
Call::MethodCall(MethodCall {
jsonrpc: Version::V2,
method: "update".to_owned(),
params: Some(Params::Array(vec![Value::U64(1), Value::U64(2)])),
id: Id::Num(1)
}),
Call::Notification(Notification {
jsonrpc: Version::V2,
method: "update".to_owned(),
params: Some(Params::Array(vec![Value::U64(1)]))
})
]))
}