cynic_parser_deser/
deserialize.rs1use std::collections::HashMap;
2
3use crate::{value::ValueType, ConstDeserializer, DeserValue, Error};
4
5pub trait ValueDeserialize<'a>: Sized {
7 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error>;
8
9 fn default_when_missing() -> Option<Self> {
11 None
12 }
13}
14
15pub trait ValueDeserializeOwned: for<'a> ValueDeserialize<'a> {}
16impl<T> ValueDeserializeOwned for T where T: for<'a> ValueDeserialize<'a> {}
17
18impl<'a> ValueDeserialize<'a> for String {
19 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
20 match input {
21 DeserValue::String(string_value) => Ok(string_value.as_str().to_string()),
22 other => Err(Error::unexpected_type(ValueType::String, other)),
23 }
24 }
25}
26
27impl<'a> ValueDeserialize<'a> for &'a str {
28 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
29 match input {
30 DeserValue::String(string_value) => Ok(string_value.as_str()),
31 other => Err(Error::unexpected_type(ValueType::String, other)),
32 }
33 }
34}
35
36impl<'a> ValueDeserialize<'a> for i32 {
37 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
38 match input {
39 DeserValue::Int(inner) => Ok(inner.as_i32()),
40 other => Err(Error::unexpected_type(ValueType::Int, other)),
41 }
42 }
43}
44
45impl<'a> ValueDeserialize<'a> for i64 {
46 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
47 match input {
48 DeserValue::Int(inner) => Ok(inner.as_i64()),
49 other => Err(Error::unexpected_type(ValueType::Int, other)),
50 }
51 }
52}
53
54impl<'a> ValueDeserialize<'a> for u32 {
55 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
56 let value = i64::deserialize(input)?;
57
58 if value < 0 {
59 return Err(Error::custom(
60 format!("integer was less than zero: {value}"),
61 input.span(),
62 ));
63 }
64
65 value
66 .try_into()
67 .map_err(|_| Error::custom(format!("integer was too large: {value}"), input.span()))
68 }
69}
70
71impl<'a> ValueDeserialize<'a> for u64 {
72 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
73 let value = i64::deserialize(input)?;
74
75 if value < 0 {
76 return Err(Error::custom(
77 format!("integer was less than zero: {value}"),
78 input.span(),
79 ));
80 }
81
82 value
83 .try_into()
84 .map_err(|_| Error::custom(format!("integer was too large: {value}"), input.span()))
85 }
86}
87
88impl<'a> ValueDeserialize<'a> for usize {
89 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
90 let value = i64::deserialize(input)?;
91
92 if value < 0 {
93 return Err(Error::custom(
94 format!("integer was less than zero: {value}"),
95 input.span(),
96 ));
97 }
98
99 value
100 .try_into()
101 .map_err(|_| Error::custom(format!("integer was too large: {value}"), input.span()))
102 }
103}
104
105impl<'a> ValueDeserialize<'a> for f64 {
106 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
107 match input {
108 DeserValue::Float(inner) => Ok(inner.as_f64()),
109 other => Err(Error::unexpected_type(ValueType::Float, other)),
110 }
111 }
112}
113
114impl<'a> ValueDeserialize<'a> for bool {
115 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
116 match input {
117 DeserValue::Boolean(inner) => Ok(inner.as_bool()),
118 other => Err(Error::unexpected_type(ValueType::Boolean, other)),
119 }
120 }
121}
122
123impl<'a> ValueDeserialize<'a> for () {
124 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
125 match input {
126 DeserValue::Null(_) => Ok(()),
127 other => Err(Error::unexpected_type(ValueType::Null, other)),
128 }
129 }
130}
131
132impl<'a, T> ValueDeserialize<'a> for Option<T>
133where
134 T: ValueDeserialize<'a>,
135{
136 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
137 match input {
138 DeserValue::Null(_) => Ok(None),
139 other => T::deserialize(other).map(Some),
140 }
141 }
142
143 fn default_when_missing() -> Option<Self> {
144 Some(None)
145 }
146}
147
148impl<'a, T> ValueDeserialize<'a> for Vec<T>
149where
150 T: ValueDeserialize<'a>,
151{
152 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
153 match input {
154 DeserValue::List(list) => list.items().map(T::deserialize).collect(),
155 other => {
156 if !other.is_null() {
157 if let Ok(inner) = T::deserialize(other) {
161 return Ok(vec![inner]);
162 }
163 }
164 Err(Error::unexpected_type(ValueType::List, other))
165 }
166 }
167 }
168}
169
170impl<'a, T> ValueDeserialize<'a> for HashMap<String, T>
171where
172 T: ValueDeserialize<'a>,
173{
174 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
175 match input {
176 DeserValue::Object(object) => Ok(object
177 .fields()
178 .map(|field| Ok((field.name().to_string(), field.value().deserialize()?)))
179 .collect::<Result<HashMap<_, _>, _>>()?),
180 other => Err(Error::unexpected_type(ValueType::Object, other)),
181 }
182 }
183}
184
185impl<'a, T> ValueDeserialize<'a> for HashMap<&'a str, T>
186where
187 T: ValueDeserialize<'a>,
188{
189 fn deserialize(input: DeserValue<'a>) -> Result<Self, Error> {
190 match input {
191 DeserValue::Object(object) => Ok(object
192 .fields()
193 .map(|field| Ok((field.name(), field.value().deserialize()?)))
194 .collect::<Result<HashMap<_, _>, _>>()?),
195 other => Err(Error::unexpected_type(ValueType::Object, other)),
196 }
197 }
198}