use juniper::Variables;
use serde::Deserialize;
use crate::util::default_for_null;
#[derive(Debug, Deserialize, PartialEq)]
#[serde(bound(deserialize = "S: Deserialize<'de>"))]
#[serde(rename_all = "camelCase")]
pub struct SubscribePayload<S> {
pub query: String,
#[serde(default, deserialize_with = "default_for_null")]
pub variables: Variables<S>,
pub operation_name: Option<String>,
#[serde(default, deserialize_with = "default_for_null")]
pub extensions: Variables<S>,
}
#[derive(Debug, Deserialize, PartialEq)]
#[serde(bound(deserialize = "S: Deserialize<'de>"))]
#[serde(rename_all = "snake_case")]
#[serde(tag = "type")]
pub enum ClientMessage<S> {
ConnectionInit {
#[serde(default, deserialize_with = "default_for_null")]
payload: Variables<S>,
},
Ping {
#[serde(default, deserialize_with = "default_for_null")]
payload: Variables<S>,
},
Pong {
#[serde(default, deserialize_with = "default_for_null")]
payload: Variables<S>,
},
Subscribe {
id: String,
payload: SubscribePayload<S>,
},
Complete {
id: String,
},
}
#[cfg(test)]
mod test {
use juniper::{DefaultScalarValue, graphql_vars};
use super::*;
#[test]
fn test_deserialization() {
type ClientMessage = super::ClientMessage<DefaultScalarValue>;
assert_eq!(
ClientMessage::ConnectionInit {
payload: graphql_vars! {"foo": "bar"},
},
serde_json::from_str(r#"{"type": "connection_init", "payload": {"foo": "bar"}}"#)
.unwrap(),
);
assert_eq!(
ClientMessage::ConnectionInit {
payload: graphql_vars! {},
},
serde_json::from_str(r#"{"type": "connection_init"}"#).unwrap(),
);
assert_eq!(
ClientMessage::Subscribe {
id: "foo".into(),
payload: SubscribePayload {
query: "query MyQuery { __typename }".into(),
variables: graphql_vars! {"foo": "bar"},
operation_name: Some("MyQuery".into()),
extensions: Default::default(),
},
},
serde_json::from_str(
r#"{"type": "subscribe", "id": "foo", "payload": {
"query": "query MyQuery { __typename }",
"variables": {
"foo": "bar"
},
"operationName": "MyQuery"
}}"#
)
.unwrap(),
);
assert_eq!(
ClientMessage::Subscribe {
id: "foo".into(),
payload: SubscribePayload {
query: "query MyQuery { __typename }".into(),
variables: graphql_vars! {},
operation_name: None,
extensions: Default::default(),
},
},
serde_json::from_str(
r#"{"type": "subscribe", "id": "foo", "payload": {
"query": "query MyQuery { __typename }"
}}"#
)
.unwrap(),
);
assert_eq!(
ClientMessage::Complete { id: "foo".into() },
serde_json::from_str(r#"{"type": "complete", "id": "foo"}"#).unwrap(),
);
}
#[test]
fn test_deserialization_of_null() -> serde_json::Result<()> {
let payload = r#"{"query":"query","variables":null}"#;
let payload: SubscribePayload<DefaultScalarValue> = serde_json::from_str(payload)?;
let expected = SubscribePayload {
query: "query".into(),
variables: graphql_vars! {},
operation_name: None,
extensions: Default::default(),
};
assert_eq!(expected, payload);
Ok(())
}
}