flow_value/
de.rs

1use crate::{Error, Map, Value, value_type::Variant};
2use rust_decimal::{Decimal, prelude::ToPrimitive};
3use serde::de::value::SeqDeserializer;
4
5pub(crate) mod const_bytes;
6mod de_enum;
7mod de_struct;
8mod text_repr;
9
10use const_bytes::ConstBytes;
11use de_enum::{EnumDeserializer, ValueEnumAccess};
12use de_struct::MapDeserializer;
13
14struct ValueVisitor;
15
16impl<'de> serde::de::Visitor<'de> for ValueVisitor {
17    type Value = Value;
18
19    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
20        f.write_str("any valid value")
21    }
22
23    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
24    where
25        A: serde::de::EnumAccess<'de>,
26    {
27        use serde::de::VariantAccess;
28        let (ty, a) = data.variant::<Variant>()?;
29        match ty {
30            Variant::Null => Ok(Value::Null),
31            Variant::String => Ok(Value::String(a.newtype_variant()?)),
32            Variant::Bool => Ok(Value::Bool(a.newtype_variant()?)),
33            Variant::U64 => Ok(Value::U64(a.newtype_variant()?)),
34            Variant::I64 => Ok(Value::I64(a.newtype_variant()?)),
35            Variant::F64 => Ok(Value::F64(a.newtype_variant()?)),
36            Variant::Decimal => Ok(Value::Decimal(Decimal::deserialize(
37                a.newtype_variant::<ConstBytes<16>>()?.0,
38            ))),
39            Variant::I128 => Ok(Value::I128(a.newtype_variant()?)),
40            Variant::U128 => Ok(Value::U128(a.newtype_variant()?)),
41            Variant::B32 => Ok(Value::B32(a.newtype_variant::<ConstBytes<32>>()?.0)),
42            Variant::B64 => Ok(Value::B64(a.newtype_variant::<ConstBytes<64>>()?.0)),
43            Variant::Bytes => Ok(Value::Bytes(a.newtype_variant()?)),
44            Variant::Array => Ok(Value::Array(a.newtype_variant()?)),
45            Variant::Map => Ok(Value::Map(a.newtype_variant()?)),
46        }
47    }
48}
49
50impl<'de> serde::Deserialize<'de> for Value {
51    /// Turn any `Deserializer` into `Value`, intended to be used
52    /// with `Value as Deserializer`.
53    fn deserialize<D>(d: D) -> Result<Self, D::Error>
54    where
55        D: serde::Deserializer<'de>,
56    {
57        if d.is_human_readable() {
58            text_repr::TextRepr::deserialize(d).map(Into::into)
59        } else {
60            d.deserialize_enum(crate::TOKEN, crate::value_type::keys::ALL, ValueVisitor)
61        }
62    }
63}
64
65impl<'de> serde::Deserializer<'de> for Value {
66    type Error = Error;
67
68    fn is_human_readable(&self) -> bool {
69        false
70    }
71
72    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
73    where
74        V: serde::de::Visitor<'de>,
75    {
76        match self {
77            Value::Null => visitor.visit_unit(),
78            Value::String(s) => visitor.visit_string(s),
79            Value::Bool(b) => visitor.visit_bool(b),
80            Value::I64(i) => visitor.visit_i64(i),
81            Value::U64(u) => visitor.visit_u64(u),
82            Value::F64(f) => visitor.visit_f64(f),
83            Value::Decimal(d) => visit_decimal(d, visitor),
84            Value::I128(i) => visitor.visit_i128(i),
85            Value::U128(u) => visitor.visit_u128(u),
86            Value::Array(array) => visit_array(array, visitor),
87            Value::Map(map) => visit_map(map, visitor),
88            Value::B32(x) => visit_bytes(&x, visitor),
89            Value::B64(x) => visit_bytes(&x, visitor),
90            Value::Bytes(x) => visit_bytes(&x, visitor),
91        }
92    }
93
94    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
95    where
96        V: serde::de::Visitor<'de>,
97    {
98        match self {
99            Value::Null => visitor.visit_none(),
100            _ => visitor.visit_some(self),
101        }
102    }
103
104    fn deserialize_newtype_struct<V>(
105        self,
106        name: &'static str,
107        visitor: V,
108    ) -> Result<V::Value, Self::Error>
109    where
110        V: serde::de::Visitor<'de>,
111    {
112        match name {
113            crate::decimal::TOKEN => match self {
114                Value::Decimal(d) => visitor.visit_bytes(&d.serialize()),
115                Value::I64(i) => visitor.visit_i64(i),
116                Value::U64(u) => visitor.visit_u64(u),
117                Value::F64(f) => visitor.visit_f64(f),
118                Value::String(s) => visitor.visit_string(s),
119                _ => Err(serde::de::Error::invalid_type(
120                    self.unexpected(),
121                    &"decimal",
122                )),
123            },
124            #[cfg(feature = "solana")]
125            crate::with::keypair::TOKEN | crate::with::signature::TOKEN => match self {
126                Value::B64(b) => visitor.visit_bytes(&b),
127                Value::Bytes(b) => visitor.visit_bytes(&b),
128                Value::String(s) => visitor.visit_str(&s),
129                Value::Array(a) => visit_array(a, visitor),
130                _ => Err(serde::de::Error::invalid_type(
131                    self.unexpected(),
132                    &"bytes or base58 string",
133                )),
134            },
135            #[cfg(feature = "solana")]
136            crate::with::pubkey::TOKEN => match self {
137                Value::B32(b) => visitor.visit_bytes(&b),
138                Value::B64(b) => visitor.visit_bytes(&b),
139                Value::Bytes(b) => visitor.visit_bytes(&b),
140                Value::String(s) => visitor.visit_str(&s),
141                Value::Array(a) => visit_array(a, visitor),
142                Value::Map(m) => visit_map(m, visitor),
143                _ => Err(serde::de::Error::invalid_type(
144                    self.unexpected(),
145                    &"public key",
146                )),
147            },
148            _ => visitor.visit_newtype_struct(self),
149        }
150    }
151
152    fn deserialize_enum<V>(
153        self,
154        name: &'static str,
155        _: &'static [&'static str],
156        visitor: V,
157    ) -> Result<V::Value, Self::Error>
158    where
159        V: serde::de::Visitor<'de>,
160    {
161        if name == crate::TOKEN {
162            visitor.visit_enum(ValueEnumAccess(self))
163        } else {
164            let (variant, value) = match self {
165                Value::Map(value) => {
166                    let mut iter = value.into_iter();
167                    let (variant, value) = match iter.next() {
168                        Some(v) => v,
169                        None => {
170                            return Err(serde::de::Error::invalid_value(
171                                serde::de::Unexpected::Map,
172                                &"map with a single key",
173                            ));
174                        }
175                    };
176                    if iter.next().is_some() {
177                        return Err(serde::de::Error::invalid_value(
178                            serde::de::Unexpected::Map,
179                            &"map with a single key",
180                        ));
181                    }
182                    (variant, Some(value))
183                }
184                Value::String(variant) => (variant, None),
185                other => {
186                    return Err(serde::de::Error::invalid_type(
187                        other.unexpected(),
188                        &"string or map",
189                    ));
190                }
191            };
192
193            visitor.visit_enum(EnumDeserializer { variant, value })
194        }
195    }
196
197    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
198    where
199        V: serde::de::Visitor<'de>,
200    {
201        match self {
202            Value::Decimal(v) => visitor.visit_bytes(&v.serialize()),
203            Value::B32(v) => visitor.visit_bytes(&v),
204            Value::B64(v) => visitor.visit_bytes(&v),
205            Value::Bytes(v) => visitor.visit_bytes(&v),
206            _ => self.deserialize_any(visitor),
207        }
208    }
209
210    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
211    where
212        V: serde::de::Visitor<'de>,
213    {
214        self.deserialize_bytes(visitor)
215    }
216
217    serde::forward_to_deserialize_any! {
218        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
219        unit unit_struct seq tuple
220        tuple_struct map struct identifier ignored_any
221    }
222}
223
224fn visit_decimal<'de, V>(mut d: Decimal, visitor: V) -> Result<V::Value, Error>
225where
226    V: serde::de::Visitor<'de>,
227{
228    d.normalize_assign();
229    if d.scale() == 0 {
230        if d.is_sign_negative() {
231            if let Some(i) = d.to_i64() {
232                return visitor.visit_i64(i);
233            }
234        } else if let Some(u) = d.to_u64() {
235            return visitor.visit_u64(u);
236        }
237    }
238
239    // this is lossy
240    if let Some(f) = d.to_f64() {
241        return visitor.visit_f64(f);
242    }
243
244    // I think to_f64 never fails, so this might be unreachable
245    visitor.visit_string(d.to_string())
246}
247
248impl Value {
249    pub(self) fn unexpected(&'_ self) -> serde::de::Unexpected<'_> {
250        use serde::de::Unexpected;
251        match self {
252            Value::Null => Unexpected::Unit,
253            Value::String(s) => Unexpected::Str(s),
254            Value::Bool(b) => Unexpected::Bool(*b),
255            Value::I64(i) => Unexpected::Signed(*i),
256            Value::U64(u) => Unexpected::Unsigned(*u),
257            Value::F64(f) => Unexpected::Float(*f),
258            Value::Decimal(_) => Unexpected::Other("decimal"),
259            Value::I128(_) => Unexpected::Other("i128"),
260            Value::U128(_) => Unexpected::Other("u128"),
261            Value::Array(_) => Unexpected::Seq,
262            Value::Map(_) => Unexpected::Map,
263            Value::B32(_) => Unexpected::Other("[u8; 32]"),
264            Value::B64(_) => Unexpected::Other("[u8; 64]"),
265            Value::Bytes(_) => Unexpected::Other("bytes"),
266        }
267    }
268}
269
270fn visit_array<'de, V>(array: Vec<Value>, visitor: V) -> Result<V::Value, Error>
271where
272    V: serde::de::Visitor<'de>,
273{
274    let mut deserializer = SeqDeserializer::<_, Error>::new(array.into_iter());
275    let seq = visitor.visit_seq(&mut deserializer)?;
276    deserializer.end()?;
277    Ok(seq)
278}
279
280fn visit_bytes<'de, V>(b: &[u8], visitor: V) -> Result<V::Value, Error>
281where
282    V: serde::de::Visitor<'de>,
283{
284    let mut deserializer = SeqDeserializer::<_, Error>::new(b.iter().cloned());
285    let seq = visitor.visit_seq(&mut deserializer)?;
286    deserializer.end()?;
287    Ok(seq)
288}
289
290impl serde::de::IntoDeserializer<'_, Error> for Value {
291    type Deserializer = Self;
292
293    fn into_deserializer(self) -> Self::Deserializer {
294        self
295    }
296}
297
298fn visit_map<'de, V>(object: Map, visitor: V) -> Result<V::Value, Error>
299where
300    V: serde::de::Visitor<'de>,
301{
302    let len = object.len();
303    let mut deserializer = MapDeserializer::new(object);
304    let map = visitor.visit_map(&mut deserializer)?;
305    let remaining = deserializer.iter.len();
306    if remaining == 0 {
307        Ok(map)
308    } else {
309        Err(serde::de::Error::invalid_length(
310            len,
311            &"fewer elements in map",
312        ))
313    }
314}
315
316#[cfg(test)]
317mod tests {
318    use super::*;
319    use rust_decimal_macros::dec;
320    use serde::Deserialize;
321    use std::collections::{HashMap, HashSet};
322
323    #[test]
324    fn value_to_value() {
325        fn t(v: Value) {
326            assert_eq!(Value::deserialize(v.clone()).unwrap(), v)
327        }
328        t(Value::Null);
329        t(Value::I64(0i64));
330        t(Value::String(String::new()));
331        t(Value::Bool(false));
332        t(Value::U64(0));
333        t(Value::I64(0));
334        t(Value::F64(0.0));
335        t(Value::Decimal(Decimal::MAX));
336        t(Value::I128(0));
337        t(Value::U128(0));
338        t(Value::B32([0u8; 32]));
339        t(Value::B64([0u8; 64]));
340        t(Value::Bytes(bytes::Bytes::from_static(
341            "something".as_bytes(),
342        )));
343        t(Value::Array(Vec::new()));
344        t(Value::Map(Map::new()));
345    }
346
347    fn de<T: serde::de::DeserializeOwned>(v: Value) -> T {
348        T::deserialize(v).unwrap()
349    }
350
351    #[test]
352    fn test_primitive() {
353        assert_eq!(de::<u8>(Value::U64(0)), 0u8);
354        assert_eq!(de::<i8>(Value::U64(0)), 0i8);
355        assert_eq!(de::<u8>(Value::I64(1)), 1u8);
356        assert_eq!(de::<i8>(Value::I64(-1)), -1i8);
357        assert_eq!(de::<f32>(Value::F64(0.0)), 0f32);
358        assert!(!de::<bool>(Value::Bool(false)));
359        assert_eq!(de::<String>(Value::String("abc".to_owned())), "abc");
360        assert_eq!(de::<f32>(Value::I64(1)), 1f32);
361    }
362
363    #[test]
364    fn test_option() {
365        assert_eq!(de::<Option<u32>>(Value::U64(0)), Some(0));
366        assert_eq!(de::<Option<()>>(Value::Null), None);
367        assert_eq!(de::<Option<Option<u32>>>(Value::U64(0)), Some(Some(0)));
368    }
369
370    #[test]
371    fn test_array() {
372        assert_eq!(
373            de::<Vec<u32>>(Value::Array([Value::U64(0), Value::U64(1)].to_vec())),
374            vec![0, 1],
375        );
376
377        assert_eq!(
378            de::<(u32, f32, Option<u64>, (i32, i32), Vec<String>)>(Value::Array(
379                [
380                    Value::U64(0),
381                    Value::F64(0.1),
382                    Value::Null,
383                    Value::Array([Value::I64(1), Value::I64(2),].to_vec()),
384                    Value::Array([Value::String("hello".to_owned())].to_vec()),
385                ]
386                .to_vec()
387            )),
388            (0u32, 0.1f32, None, (1, 2), ["hello".to_owned()].to_vec()),
389        );
390
391        assert_eq!(
392            de::<HashSet<u32>>(Value::Array([Value::U64(0), Value::U64(1)].to_vec())),
393            HashSet::from([0, 1]),
394        );
395    }
396
397    #[test]
398    fn test_wrapper_struct() {
399        #[derive(Deserialize, Debug, PartialEq)]
400        struct Unit;
401        assert_eq!(de::<Unit>(Value::Null), Unit);
402
403        #[derive(Deserialize, Debug, PartialEq)]
404        struct Unit1();
405        assert_eq!(de::<Unit1>(Value::Array(Vec::new())), Unit1());
406
407        #[derive(Deserialize, Debug, PartialEq)]
408        struct NewTypeStruct(i64);
409        assert_eq!(de::<NewTypeStruct>(Value::I64(0)), NewTypeStruct(0));
410
411        #[derive(Deserialize, Debug, PartialEq)]
412        struct NewTypeStructTuple((i32,));
413        assert_eq!(
414            de::<NewTypeStructTuple>(Value::Array([Value::I64(0)].to_vec())),
415            NewTypeStructTuple((0,))
416        );
417
418        #[derive(Deserialize, Debug, PartialEq)]
419        struct TupleStruct(i32, String, (i32, i32), (), ((),));
420        assert_eq!(
421            de::<TupleStruct>(Value::Array(
422                [
423                    Value::I64(0),
424                    Value::String("hello".to_owned()),
425                    Value::Array([Value::I64(1), Value::I64(2)].to_vec()),
426                    Value::Null,
427                    Value::Array([Value::Null].to_vec()),
428                ]
429                .to_vec()
430            )),
431            TupleStruct(0, "hello".to_owned(), (1, 2), (), ((),))
432        );
433    }
434
435    fn bool_true() -> bool {
436        true
437    }
438
439    fn some_3() -> Option<u32> {
440        Some(3)
441    }
442
443    #[test]
444    fn test_map() {
445        assert_eq!(
446            de::<HashMap<i32, i32>>(Value::Map(Map::from([
447                ("1".to_owned(), Value::I64(2)),
448                ("3".to_owned(), Value::I64(4))
449            ]))),
450            HashMap::<i32, i32>::from([(1, 2), (3, 4)])
451        );
452
453        #[derive(Deserialize, Debug, PartialEq)]
454        struct Struct {
455            x: i32,
456            #[serde(default = "bool_true")]
457            b0: bool,
458            #[serde(rename = "bb")]
459            b1: bool,
460            #[serde(flatten)]
461            flat: Flat,
462        }
463        #[derive(Deserialize, Debug, PartialEq)]
464        struct Flat {
465            k: String,
466            #[serde(default = "bool_true")]
467            b1: bool,
468            #[serde(default = "some_3")]
469            opt: Option<u32>,
470        }
471        assert_eq!(
472            de::<Struct>(Value::Map(Map::from([
473                ("x".to_owned(), Value::I64(1)),
474                ("bb".to_owned(), Value::Bool(false)),
475                ("k".to_owned(), Value::String("hello".to_owned())),
476            ]))),
477            Struct {
478                x: 1,
479                b0: true,
480                b1: false,
481                flat: Flat {
482                    k: "hello".to_owned(),
483                    b1: true,
484                    opt: Some(3),
485                },
486            }
487        );
488    }
489
490    #[test]
491    fn test_enum() {
492        #[derive(Deserialize, PartialEq, Debug)]
493        enum Enum {
494            Var1,
495            Var2,
496            #[serde(rename = "hello")]
497            Var3,
498        }
499        assert_eq!(de::<Enum>(Value::String("Var1".to_owned())), Enum::Var1);
500        assert_eq!(de::<Enum>(Value::String("Var2".to_owned())), Enum::Var2);
501        assert_eq!(de::<Enum>(Value::String("hello".to_owned())), Enum::Var3);
502
503        #[derive(Deserialize, PartialEq, Debug)]
504        #[serde(untagged)]
505        enum Enum1 {
506            A { a: u32 },
507            BC { b: Option<u32>, c: Option<u32> },
508        }
509        assert_eq!(
510            de::<Enum1>(Value::Map(Map::from([("a".to_owned(), Value::U64(0))]))),
511            Enum1::A { a: 0 }
512        );
513        assert_eq!(
514            de::<Enum1>(Value::Map(Map::new())),
515            Enum1::BC { b: None, c: None }
516        );
517
518        #[derive(Deserialize, PartialEq, Debug)]
519        enum Enum2 {
520            A { a: u32 },
521            BC { b: Option<u32>, c: Option<u32> },
522            D,
523            E(f32),
524        }
525        assert_eq!(
526            de::<Enum2>(Value::Map(Map::from([(
527                "A".to_owned(),
528                Value::Map(Map::from([("a".to_owned(), Value::U64(0))]))
529            )]))),
530            Enum2::A { a: 0 }
531        );
532        assert_eq!(
533            de::<Enum2>(Value::Map(Map::from([(
534                "BC".to_owned(),
535                Value::Map(Map::new())
536            )]))),
537            Enum2::BC { b: None, c: None }
538        );
539        assert_eq!(
540            de::<Enum2>(Value::Map(Map::from([("D".to_owned(), Value::Null)]))),
541            Enum2::D,
542        );
543        assert_eq!(
544            de::<Enum2>(Value::Map(Map::from([("E".to_owned(), Value::F64(0.0),)]))),
545            Enum2::E(0.0),
546        );
547    }
548
549    #[test]
550    fn test_decimal() {
551        assert_eq!(de::<u32>(Value::Decimal(dec!(100.0))), 100);
552        assert_eq!(de::<f32>(Value::Decimal(dec!(100))), 100.0);
553        assert_eq!(de::<f64>(Value::Decimal(dec!(1999.1234))), 1999.1234);
554        assert_eq!(
555            de::<f64>(Value::Decimal(Decimal::MAX)),
556            7.922816251426434e28
557        );
558        assert_eq!(de::<u64>(Value::Decimal(Decimal::from(u64::MAX))), u64::MAX);
559    }
560}