1use serde::de::{DeserializeSeed, Deserializer, Error as _, MapAccess, SeqAccess, Visitor};
30use serde::ser::{Error as _, Serialize, SerializeMap, SerializeSeq, Serializer};
31use std::fmt;
32use toasty_core::stmt::{self, Value};
33
34pub struct Encode<'a>(pub &'a Value);
47
48impl Serialize for Encode<'_> {
49 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
50 match self.0 {
51 Value::Null => s.serialize_unit(),
52 Value::Bool(v) => s.serialize_bool(*v),
53 Value::I8(v) => s.serialize_i8(*v),
54 Value::I16(v) => s.serialize_i16(*v),
55 Value::I32(v) => s.serialize_i32(*v),
56 Value::I64(v) => s.serialize_i64(*v),
57 Value::U8(v) => s.serialize_u8(*v),
58 Value::U16(v) => s.serialize_u16(*v),
59 Value::U32(v) => s.serialize_u32(*v),
60 Value::U64(v) => s.serialize_u64(*v),
61 Value::F32(v) if v.is_finite() => s.serialize_f32(*v),
63 Value::F32(_) => s.serialize_unit(),
64 Value::F64(v) if v.is_finite() => s.serialize_f64(*v),
65 Value::F64(_) => s.serialize_unit(),
66 Value::String(v) => s.serialize_str(v),
67 Value::Uuid(v) => s.collect_str(v),
68 Value::List(items) => {
69 let mut seq = s.serialize_seq(Some(items.len()))?;
70 for item in items {
71 seq.serialize_element(&Encode(item))?;
72 }
73 seq.end()
74 }
75 Value::Object(object) => {
76 let mut map = s.serialize_map(None)?;
77 for (k, v) in object.iter() {
78 if v.is_null() {
80 continue;
81 }
82 map.serialize_entry(k, &Encode(v))?;
83 }
84 map.end()
85 }
86 #[cfg(feature = "rust_decimal")]
98 v @ Value::Decimal(_) => s.collect_str(
99 &v.document_storage_text()
100 .expect("decimal value has a document text form"),
101 ),
102 #[cfg(feature = "bigdecimal")]
103 v @ Value::BigDecimal(_) => s.collect_str(
104 &v.document_storage_text()
105 .expect("decimal value has a document text form"),
106 ),
107 #[cfg(feature = "jiff")]
108 v @ (Value::Timestamp(_) | Value::Date(_) | Value::Time(_) | Value::DateTime(_)) => {
109 let text = v
110 .document_storage_text()
111 .expect("temporal value has a document text form");
112 s.collect_str(&text)
113 }
114 #[cfg(feature = "jiff")]
115 Value::Zoned(v) => s.collect_str(v),
116 other => Err(S::Error::custom(format!("cannot encode {other:?} as JSON"))),
117 }
118 }
119}
120
121pub fn to_string(value: &Value) -> Result<String, serde_json::Error> {
123 serde_json::to_string(&Encode(value))
124}
125
126pub fn to_vec(value: &Value) -> Result<Vec<u8>, serde_json::Error> {
128 serde_json::to_vec(&Encode(value))
129}
130
131pub struct Seed<'a> {
142 pub ty: &'a stmt::Type,
144}
145
146impl<'de> DeserializeSeed<'de> for Seed<'_> {
147 type Value = Value;
148
149 fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<Value, D::Error> {
150 de.deserialize_any(ValueVisitor { ty: self.ty })
153 }
154}
155
156struct ValueVisitor<'a> {
157 ty: &'a stmt::Type,
158}
159
160struct AnySeed;
167
168impl<'de> DeserializeSeed<'de> for AnySeed {
169 type Value = Value;
170
171 fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<Value, D::Error> {
172 de.deserialize_any(AnyVisitor)
173 }
174}
175
176struct AnyVisitor;
177
178impl<'de> Visitor<'de> for AnyVisitor {
179 type Value = Value;
180
181 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 write!(f, "a JSON value inside a document")
183 }
184
185 fn visit_unit<E: serde::de::Error>(self) -> Result<Value, E> {
186 Ok(Value::Null)
187 }
188
189 fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<Value, E> {
190 Ok(Value::Bool(v))
191 }
192
193 fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Value, E> {
194 Ok(Value::I64(v))
195 }
196
197 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Value, E> {
198 Ok(match i64::try_from(v) {
201 Ok(v) => Value::I64(v),
202 Err(_) => Value::U64(v),
203 })
204 }
205
206 fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<Value, E> {
207 Ok(Value::F64(v))
208 }
209
210 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Value, E> {
211 Ok(Value::String(v.to_owned()))
212 }
213
214 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Value, A::Error> {
215 let mut items = Vec::with_capacity(seq.size_hint().unwrap_or(0));
216 while let Some(value) = seq.next_element_seed(AnySeed)? {
217 items.push(value);
218 }
219 Ok(Value::List(items))
220 }
221
222 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Value, A::Error> {
223 let mut entries = Vec::new();
224 while let Some(key) = map.next_key::<String>()? {
225 entries.push((key, map.next_value_seed(AnySeed)?));
226 }
227 Ok(Value::Object(stmt::ValueObject::from_vec(entries)))
228 }
229}
230
231impl<'de> Visitor<'de> for ValueVisitor<'_> {
232 type Value = Value;
233
234 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 write!(f, "a JSON value decodable as {:?}", self.ty)
236 }
237
238 fn visit_unit<E: serde::de::Error>(self) -> Result<Value, E> {
239 Ok(Value::Null)
242 }
243
244 fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<Value, E> {
245 match self.ty {
246 stmt::Type::Bool => Ok(Value::Bool(v)),
247 other => Err(E::custom(format!(
248 "unexpected JSON bool for type {other:?}"
249 ))),
250 }
251 }
252
253 fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Value, E> {
254 int_to_value(self.ty, v as i128)
255 }
256
257 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Value, E> {
258 int_to_value(self.ty, v as i128)
259 }
260
261 fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<Value, E> {
262 match self.ty {
263 stmt::Type::F32 => Ok(Value::F32(v as f32)),
264 stmt::Type::F64 => Ok(Value::F64(v)),
265 other => Err(E::custom(format!(
266 "unexpected JSON float for type {other:?}"
267 ))),
268 }
269 }
270
271 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Value, E> {
272 match self.ty {
273 stmt::Type::String => Ok(Value::String(v.to_owned())),
274 stmt::Type::Uuid => Ok(Value::Uuid(v.parse().map_err(E::custom)?)),
275 #[cfg(feature = "rust_decimal")]
276 stmt::Type::Decimal => Ok(Value::Decimal(v.parse().map_err(E::custom)?)),
277 #[cfg(feature = "bigdecimal")]
278 stmt::Type::BigDecimal => Ok(Value::BigDecimal(v.parse().map_err(E::custom)?)),
279 #[cfg(feature = "jiff")]
280 stmt::Type::Timestamp => Ok(Value::Timestamp(v.parse().map_err(E::custom)?)),
281 #[cfg(feature = "jiff")]
282 stmt::Type::Zoned => Ok(Value::Zoned(v.parse().map_err(E::custom)?)),
283 #[cfg(feature = "jiff")]
284 stmt::Type::Date => Ok(Value::Date(v.parse().map_err(E::custom)?)),
285 #[cfg(feature = "jiff")]
286 stmt::Type::Time => Ok(Value::Time(v.parse().map_err(E::custom)?)),
287 #[cfg(feature = "jiff")]
288 stmt::Type::DateTime => Ok(Value::DateTime(v.parse().map_err(E::custom)?)),
289 other => Err(E::custom(format!(
290 "unexpected JSON string for type {other:?}"
291 ))),
292 }
293 }
294
295 fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Value, A::Error> {
296 match self.ty {
297 stmt::Type::List(elem) => read_seq(seq, elem),
298 other => Err(A::Error::custom(format!(
299 "unexpected JSON array for type {other:?}"
300 ))),
301 }
302 }
303
304 fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Value, A::Error> {
305 match self.ty {
310 stmt::Type::Object => AnyVisitor.visit_map(map),
311 other => Err(A::Error::custom(format!(
312 "unexpected JSON object for type {other:?}"
313 ))),
314 }
315 }
316}
317
318fn int_to_value<E: serde::de::Error>(ty: &stmt::Type, v: i128) -> Result<Value, E> {
324 fn checked<T: TryFrom<i128>, E: serde::de::Error>(v: i128, ty: &stmt::Type) -> Result<T, E> {
325 T::try_from(v)
326 .map_err(|_| E::custom(format!("JSON integer {v} is out of range for type {ty:?}")))
327 }
328
329 Ok(match ty {
330 stmt::Type::I8 => Value::I8(checked(v, ty)?),
331 stmt::Type::I16 => Value::I16(checked(v, ty)?),
332 stmt::Type::I32 => Value::I32(checked(v, ty)?),
333 stmt::Type::I64 => Value::I64(checked(v, ty)?),
334 stmt::Type::U8 => Value::U8(checked(v, ty)?),
335 stmt::Type::U16 => Value::U16(checked(v, ty)?),
336 stmt::Type::U32 => Value::U32(checked(v, ty)?),
337 stmt::Type::U64 => Value::U64(checked(v, ty)?),
338 stmt::Type::F32 => Value::F32(v as f32),
339 stmt::Type::F64 => Value::F64(v as f64),
340 other => {
341 return Err(E::custom(format!(
342 "unexpected JSON integer for type {other:?}"
343 )));
344 }
345 })
346}
347
348fn read_seq<'de, A: SeqAccess<'de>>(mut seq: A, elem_ty: &stmt::Type) -> Result<Value, A::Error> {
351 let mut items = Vec::with_capacity(seq.size_hint().unwrap_or(0));
352 while let Some(value) = seq.next_element_seed(Seed { ty: elem_ty })? {
353 items.push(value);
354 }
355 Ok(Value::List(items))
356}
357
358struct ListVisitor<'a> {
362 elem_ty: &'a stmt::Type,
363}
364
365impl<'de> Visitor<'de> for ListVisitor<'_> {
366 type Value = Value;
367
368 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369 write!(f, "a JSON array of {:?}", self.elem_ty)
370 }
371
372 fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Value, A::Error> {
373 read_seq(seq, self.elem_ty)
374 }
375}
376
377pub fn from_str(text: &str, ty: &stmt::Type) -> Result<Value, serde_json::Error> {
379 let mut de = serde_json::Deserializer::from_str(text);
380 let value = Seed { ty }.deserialize(&mut de)?;
381 de.end()?;
382 Ok(value)
383}
384
385pub fn from_slice(bytes: &[u8], ty: &stmt::Type) -> Result<Value, serde_json::Error> {
387 let mut de = serde_json::Deserializer::from_slice(bytes);
388 let value = Seed { ty }.deserialize(&mut de)?;
389 de.end()?;
390 Ok(value)
391}
392
393pub fn list_from_str(text: &str, elem_ty: &stmt::Type) -> Result<Value, serde_json::Error> {
396 let mut de = serde_json::Deserializer::from_str(text);
397 let value = de.deserialize_seq(ListVisitor { elem_ty })?;
398 de.end()?;
399 Ok(value)
400}
401
402pub fn list_from_slice(bytes: &[u8], elem_ty: &stmt::Type) -> Result<Value, serde_json::Error> {
405 let mut de = serde_json::Deserializer::from_slice(bytes);
406 let value = de.deserialize_seq(ListVisitor { elem_ty })?;
407 de.end()?;
408 Ok(value)
409}