juniper_puff/integrations/
serde.rs1use std::{fmt, marker::PhantomData};
2
3use indexmap::IndexMap;
4use serde::{
5 de::{self, Deserializer, IntoDeserializer as _},
6 ser::{SerializeMap as _, Serializer},
7 serde_if_integer128, Deserialize, Serialize,
8};
9
10use crate::{
11 ast::InputValue,
12 executor::ExecutionError,
13 parser::{ParseError, SourcePosition, Spanning},
14 validation::RuleError,
15 DefaultScalarValue, GraphQLError, Object, Value,
16};
17
18impl<T: Serialize> Serialize for ExecutionError<T> {
19 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
20 let mut map = ser.serialize_map(Some(4))?;
21
22 map.serialize_key("message")?;
23 map.serialize_value(self.error().message())?;
24
25 let locations = vec![self.location()];
26 map.serialize_key("locations")?;
27 map.serialize_value(&locations)?;
28
29 map.serialize_key("path")?;
30 map.serialize_value(self.path())?;
31
32 if !self.error().extensions().is_null() {
33 map.serialize_key("extensions")?;
34 map.serialize_value(self.error().extensions())?;
35 }
36
37 map.end()
38 }
39}
40
41impl Serialize for GraphQLError {
42 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
43 #[derive(Serialize)]
44 struct Helper {
45 message: &'static str,
46 }
47
48 match self {
49 Self::ParseError(e) => [e].serialize(ser),
50 Self::ValidationError(es) => es.serialize(ser),
51 Self::NoOperationProvided => [Helper {
52 message: "Must provide an operation",
53 }]
54 .serialize(ser),
55 Self::MultipleOperationsProvided => [Helper {
56 message: "Must provide operation name \
57 if query contains multiple operations",
58 }]
59 .serialize(ser),
60 Self::UnknownOperationName => [Helper {
61 message: "Unknown operation",
62 }]
63 .serialize(ser),
64 Self::IsSubscription => [Helper {
65 message: "Expected query, got subscription",
66 }]
67 .serialize(ser),
68 Self::NotSubscription => [Helper {
69 message: "Expected subscription, got query",
70 }]
71 .serialize(ser),
72 }
73 }
74}
75
76impl<'de, S: Deserialize<'de>> Deserialize<'de> for InputValue<S> {
77 fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
78 struct Visitor<S: ?Sized>(PhantomData<S>);
79
80 impl<'de, S: Deserialize<'de>> de::Visitor<'de> for Visitor<S> {
81 type Value = InputValue<S>;
82
83 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 f.write_str("a valid input value")
85 }
86
87 fn visit_bool<E: de::Error>(self, b: bool) -> Result<Self::Value, E> {
88 S::deserialize(b.into_deserializer()).map(InputValue::Scalar)
89 }
90
91 fn visit_i8<E: de::Error>(self, n: i8) -> Result<Self::Value, E> {
92 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
93 }
94
95 fn visit_i16<E: de::Error>(self, n: i16) -> Result<Self::Value, E> {
96 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
97 }
98
99 fn visit_i32<E: de::Error>(self, n: i32) -> Result<Self::Value, E> {
100 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
101 }
102
103 fn visit_i64<E: de::Error>(self, n: i64) -> Result<Self::Value, E> {
104 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
105 }
106
107 serde_if_integer128! {
108 fn visit_i128<E: de::Error>(self, n: i128) -> Result<Self::Value, E> {
109 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
110 }
111 }
112
113 fn visit_u8<E: de::Error>(self, n: u8) -> Result<Self::Value, E> {
114 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
115 }
116
117 fn visit_u16<E: de::Error>(self, n: u16) -> Result<Self::Value, E> {
118 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
119 }
120
121 fn visit_u32<E: de::Error>(self, n: u32) -> Result<Self::Value, E> {
122 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
123 }
124
125 fn visit_u64<E: de::Error>(self, n: u64) -> Result<Self::Value, E> {
126 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
127 }
128
129 serde_if_integer128! {
130 fn visit_u128<E: de::Error>(self, n: u128) -> Result<Self::Value, E> {
131 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
132 }
133 }
134
135 fn visit_f32<E: de::Error>(self, n: f32) -> Result<Self::Value, E> {
136 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
137 }
138
139 fn visit_f64<E: de::Error>(self, n: f64) -> Result<Self::Value, E> {
140 S::deserialize(n.into_deserializer()).map(InputValue::Scalar)
141 }
142
143 fn visit_char<E: de::Error>(self, c: char) -> Result<Self::Value, E> {
144 S::deserialize(c.into_deserializer()).map(InputValue::Scalar)
145 }
146
147 fn visit_str<E: de::Error>(self, s: &str) -> Result<Self::Value, E> {
148 S::deserialize(s.into_deserializer()).map(InputValue::Scalar)
149 }
150
151 fn visit_string<E: de::Error>(self, s: String) -> Result<Self::Value, E> {
152 S::deserialize(s.into_deserializer()).map(InputValue::Scalar)
153 }
154
155 fn visit_bytes<E: de::Error>(self, b: &[u8]) -> Result<Self::Value, E> {
156 S::deserialize(b.into_deserializer()).map(InputValue::Scalar)
157 }
158
159 fn visit_byte_buf<E: de::Error>(self, b: Vec<u8>) -> Result<Self::Value, E> {
160 S::deserialize(b.into_deserializer()).map(InputValue::Scalar)
161 }
162
163 fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
164 Ok(InputValue::Null)
165 }
166
167 fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
168 Ok(InputValue::Null)
169 }
170
171 fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
172 where
173 V: de::SeqAccess<'de>,
174 {
175 let mut vals = Vec::new();
176 while let Some(v) = visitor.next_element()? {
177 vals.push(v);
178 }
179 Ok(InputValue::list(vals))
180 }
181
182 fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
183 where
184 V: de::MapAccess<'de>,
185 {
186 let mut obj = IndexMap::<String, InputValue<S>>::with_capacity(
187 visitor.size_hint().unwrap_or(0),
188 );
189 while let Some((key, val)) = visitor.next_entry()? {
190 obj.insert(key, val);
191 }
192 Ok(InputValue::object(obj))
193 }
194 }
195
196 de.deserialize_any(Visitor(PhantomData))
197 }
198}
199
200impl<T: Serialize> Serialize for InputValue<T> {
201 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
202 match self {
203 Self::Null | Self::Variable(_) => ser.serialize_unit(),
204 Self::Scalar(s) => s.serialize(ser),
205 Self::Enum(e) => ser.serialize_str(e),
206 Self::List(l) => l.iter().map(|x| &x.item).collect::<Vec<_>>().serialize(ser),
207 Self::Object(o) => o
208 .iter()
209 .map(|(k, v)| (k.item.as_str(), &v.item))
210 .collect::<IndexMap<_, _>>()
211 .serialize(ser),
212 }
213 }
214}
215
216impl Serialize for RuleError {
217 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
218 let mut map = ser.serialize_map(Some(2))?;
219
220 map.serialize_key("message")?;
221 map.serialize_value(self.message())?;
222
223 map.serialize_key("locations")?;
224 map.serialize_value(self.locations())?;
225
226 map.end()
227 }
228}
229
230impl Serialize for SourcePosition {
231 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
232 let mut map = ser.serialize_map(Some(2))?;
233
234 let line = self.line() + 1;
235 map.serialize_key("line")?;
236 map.serialize_value(&line)?;
237
238 let column = self.column() + 1;
239 map.serialize_key("column")?;
240 map.serialize_value(&column)?;
241
242 map.end()
243 }
244}
245
246impl Serialize for Spanning<ParseError> {
247 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
248 let mut map = ser.serialize_map(Some(2))?;
249
250 let msg = self.item.to_string();
251 map.serialize_key("message")?;
252 map.serialize_value(&msg)?;
253
254 let mut loc = IndexMap::new();
255 loc.insert("line".to_owned(), self.start.line() + 1);
256 loc.insert("column".to_owned(), self.start.column() + 1);
257
258 let locations = vec![loc];
259 map.serialize_key("locations")?;
260 map.serialize_value(&locations)?;
261
262 map.end()
263 }
264}
265
266impl<T: Serialize> Serialize for Object<T> {
267 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
268 let mut map = ser.serialize_map(Some(self.field_count()))?;
269 for (f, v) in self.iter() {
270 map.serialize_key(f)?;
271 map.serialize_value(v)?;
272 }
273 map.end()
274 }
275}
276
277impl<T: Serialize> Serialize for Value<T> {
278 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
279 match self {
280 Self::Null => ser.serialize_unit(),
281 Self::Scalar(s) => s.serialize(ser),
282 Self::List(l) => l.serialize(ser),
283 Self::Object(o) => o.serialize(ser),
284 }
285 }
286}
287
288impl<'de> Deserialize<'de> for DefaultScalarValue {
289 fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
290 struct Visitor;
291
292 impl<'de> de::Visitor<'de> for Visitor {
293 type Value = DefaultScalarValue;
294
295 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
296 f.write_str("a valid input value")
297 }
298
299 fn visit_bool<E: de::Error>(self, b: bool) -> Result<Self::Value, E> {
300 Ok(DefaultScalarValue::Boolean(b))
301 }
302
303 fn visit_i64<E: de::Error>(self, n: i64) -> Result<Self::Value, E> {
304 if n >= i64::from(i32::MIN) && n <= i64::from(i32::MAX) {
305 Ok(DefaultScalarValue::Int(n.try_into().unwrap()))
306 } else {
307 Ok(DefaultScalarValue::Float(n as f64))
315 }
316 }
317
318 fn visit_u64<E: de::Error>(self, n: u64) -> Result<Self::Value, E> {
319 if n <= u64::try_from(i32::MAX).unwrap() {
320 self.visit_i64(n.try_into().unwrap())
321 } else {
322 Ok(DefaultScalarValue::Float(n as f64))
330 }
331 }
332
333 fn visit_f64<E: de::Error>(self, f: f64) -> Result<Self::Value, E> {
334 Ok(DefaultScalarValue::Float(f))
335 }
336
337 fn visit_str<E: de::Error>(self, s: &str) -> Result<Self::Value, E> {
338 self.visit_string(s.into())
339 }
340
341 fn visit_string<E: de::Error>(self, s: String) -> Result<Self::Value, E> {
342 Ok(DefaultScalarValue::String(s))
343 }
344 }
345
346 de.deserialize_any(Visitor)
347 }
348}
349
350#[cfg(test)]
351mod tests {
352 use serde_json::{from_str, to_string};
353
354 use crate::{
355 ast::InputValue,
356 graphql_input_value,
357 value::{DefaultScalarValue, Object},
358 FieldError, Value,
359 };
360
361 use super::{ExecutionError, GraphQLError};
362
363 #[test]
364 fn int() {
365 assert_eq!(
366 from_str::<InputValue>("1235").unwrap(),
367 graphql_input_value!(1235),
368 );
369 }
370
371 #[test]
372 fn float() {
373 assert_eq!(
374 from_str::<InputValue>("2.0").unwrap(),
375 graphql_input_value!(2.0),
376 );
377 assert_eq!(
379 from_str::<InputValue>("123567890123").unwrap(),
380 graphql_input_value!(123_567_890_123.0),
381 );
382 }
383
384 #[test]
385 fn errors() {
386 assert_eq!(
387 to_string(&GraphQLError::UnknownOperationName).unwrap(),
388 r#"[{"message":"Unknown operation"}]"#,
389 );
390 }
391
392 #[test]
393 fn error_extensions() {
394 let mut obj: Object<DefaultScalarValue> = Object::with_capacity(1);
395 obj.add_field("foo", Value::scalar("bar"));
396 assert_eq!(
397 to_string(&ExecutionError::at_origin(FieldError::new(
398 "foo error",
399 Value::Object(obj),
400 )))
401 .unwrap(),
402 r#"{"message":"foo error","locations":[{"line":1,"column":1}],"path":[],"extensions":{"foo":"bar"}}"#,
403 );
404 }
405}