1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate graphql_query_derive;
#[cfg(test)]
#[macro_use]
extern crate serde_json;
#[doc(hidden)]
pub use graphql_query_derive::*;
pub trait GraphQLQuery<'de> {
type Variables: serde::Serialize;
type ResponseData: serde::Deserialize<'de>;
fn build_query(variables: Self::Variables) -> GraphQLQueryBody<Self::Variables>;
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GraphQLQueryBody<Variables>
where
Variables: serde::Serialize,
{
pub variables: Variables,
pub query: &'static str,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Location {
line: i32,
column: i32,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum PathFragment {
Key(String),
Index(i32),
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GraphQLError {
pub message: String,
pub locations: Option<Vec<Location>>,
pub path: Option<Vec<PathFragment>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GraphQLResponse<Data> {
pub data: Option<Data>,
pub errors: Option<Vec<GraphQLError>>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn graphql_error_works_with_just_message() {
let err = json!({
"message": "I accidentally your whole query"
});
let deserialized_error: GraphQLError = serde_json::from_value(err).unwrap();
assert_eq!(
deserialized_error,
GraphQLError {
message: "I accidentally your whole query".to_string(),
locations: None,
path: None,
}
)
}
#[test]
fn full_graphql_error_deserialization() {
let err = json!({
"message": "I accidentally your whole query",
"locations": [{ "line": 3, "column": 13}, {"line": 56, "column": 1}],
"path": ["home", "alone", 3, "rating"]
});
let deserialized_error: GraphQLError = serde_json::from_value(err).unwrap();
assert_eq!(
deserialized_error,
GraphQLError {
message: "I accidentally your whole query".to_string(),
locations: Some(vec![
Location {
line: 3,
column: 13,
},
Location {
line: 56,
column: 1,
},
]),
path: Some(vec![
PathFragment::Key("home".to_owned()),
PathFragment::Key("alone".to_owned()),
PathFragment::Index(3),
PathFragment::Key("rating".to_owned()),
]),
}
)
}
}