musli_value/
value.rs

1#[cfg(feature = "alloc")]
2use alloc::borrow::ToOwned;
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::string::String;
7#[cfg(feature = "alloc")]
8use alloc::vec::Vec;
9
10use musli::de::{AsDecoder, Decode, Decoder, NumberVisitor, Visitor};
11#[cfg(feature = "alloc")]
12use musli::de::{
13    EntryDecoder, MapDecoder, SequenceDecoder, SizeHint, ValueVisitor, VariantDecoder,
14};
15use musli::en::{Encode, Encoder};
16#[cfg(feature = "alloc")]
17use musli::en::{MapEncoder, SequenceEncoder, VariantEncoder};
18use musli::Context;
19use musli_utils::Options;
20
21use crate::de::ValueDecoder;
22use crate::type_hint::{NumberHint, TypeHint};
23
24/// A dynamic value capable of representing any [Müsli] type whether it be
25/// complex or simple.
26///
27/// [Müsli]: https://github.com/udoprog/musli
28#[derive(Debug, Clone, PartialEq, PartialOrd)]
29#[non_exhaustive]
30pub enum Value {
31    /// The default unit value.
32    Unit,
33    /// A boolean value.
34    Bool(bool),
35    /// A character.
36    Char(char),
37    /// A number.
38    Number(Number),
39    /// An array.
40    #[cfg(feature = "alloc")]
41    Bytes(Vec<u8>),
42    /// A string in a value.
43    #[cfg(feature = "alloc")]
44    String(String),
45    /// A unit value.
46    #[cfg(feature = "alloc")]
47    Sequence(Vec<Value>),
48    /// A pair stored in the value.
49    #[cfg(feature = "alloc")]
50    Map(Vec<(Value, Value)>),
51    /// A variant pair. The first value identifies the variant, the second value
52    /// contains the value of the variant.
53    #[cfg(feature = "alloc")]
54    Variant(Box<(Value, Value)>),
55    /// An optional value.
56    #[cfg(feature = "alloc")]
57    Option(Option<Box<Value>>),
58}
59
60impl Value {
61    /// Construct a [AsValueDecoder] implementation out of this value which
62    /// emits the specified error `E`.
63    #[inline]
64    pub fn into_value_decoder<const OPT: Options, C: ?Sized>(
65        self,
66        cx: &C,
67    ) -> AsValueDecoder<'_, OPT, C> {
68        AsValueDecoder::new(cx, self)
69    }
70
71    /// Get a decoder associated with a value.
72    #[inline]
73    pub(crate) fn decoder<'a, 'de, const OPT: Options, C: ?Sized>(
74        &'de self,
75        cx: &'a C,
76    ) -> ValueDecoder<'a, 'de, OPT, C> {
77        ValueDecoder::new(cx, self)
78    }
79
80    /// Get the type hint corresponding to the value.
81    pub(crate) fn type_hint(&self) -> TypeHint {
82        match self {
83            Value::Unit => TypeHint::Unit,
84            Value::Bool(..) => TypeHint::Bool,
85            Value::Char(..) => TypeHint::Char,
86            Value::Number(number) => TypeHint::Number(number.type_hint()),
87            #[cfg(feature = "alloc")]
88            Value::Bytes(bytes) => TypeHint::Bytes(SizeHint::Exact(bytes.len())),
89            #[cfg(feature = "alloc")]
90            Value::String(string) => TypeHint::String(SizeHint::Exact(string.len())),
91            #[cfg(feature = "alloc")]
92            Value::Sequence(sequence) => TypeHint::Sequence(SizeHint::Exact(sequence.len())),
93            #[cfg(feature = "alloc")]
94            Value::Map(map) => TypeHint::Map(SizeHint::Exact(map.len())),
95            #[cfg(feature = "alloc")]
96            Value::Variant(..) => TypeHint::Variant,
97            #[cfg(feature = "alloc")]
98            Value::Option(..) => TypeHint::Option,
99        }
100    }
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
104#[non_exhaustive]
105pub enum Number {
106    /// `u8`
107    U8(u8),
108    /// `u16`
109    U16(u16),
110    /// `u32`
111    U32(u32),
112    /// `u64`
113    U64(u64),
114    /// `u128`
115    U128(u128),
116    /// `u8`
117    I8(i8),
118    /// `u16`
119    I16(i16),
120    /// `u32`
121    I32(i32),
122    /// `u64`
123    I64(i64),
124    /// `u128`
125    I128(i128),
126    /// `usize`
127    Usize(usize),
128    /// `isize`
129    Isize(isize),
130    /// `f32`
131    F32(f32),
132    /// `f64`
133    F64(f64),
134}
135
136macro_rules! from {
137    ($ty:ty, $variant:ident) => {
138        impl From<$ty> for Number {
139            fn from(value: $ty) -> Self {
140                Self::$variant(value)
141            }
142        }
143    };
144}
145
146from!(u8, U8);
147from!(u16, U16);
148from!(u32, U32);
149from!(u64, U64);
150from!(u128, U128);
151from!(i8, I8);
152from!(i16, I16);
153from!(i32, I32);
154from!(i64, I64);
155from!(i128, I128);
156from!(usize, Usize);
157from!(isize, Isize);
158from!(f32, F32);
159from!(f64, F64);
160
161impl<M> Encode<M> for Number {
162    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
163    where
164        E: Encoder<Mode = M>,
165    {
166        match self {
167            Number::U8(n) => encoder.encode_u8(*n),
168            Number::U16(n) => encoder.encode_u16(*n),
169            Number::U32(n) => encoder.encode_u32(*n),
170            Number::U64(n) => encoder.encode_u64(*n),
171            Number::U128(n) => encoder.encode_u128(*n),
172            Number::I8(n) => encoder.encode_i8(*n),
173            Number::I16(n) => encoder.encode_i16(*n),
174            Number::I32(n) => encoder.encode_i32(*n),
175            Number::I64(n) => encoder.encode_i64(*n),
176            Number::I128(n) => encoder.encode_i128(*n),
177            Number::Usize(n) => encoder.encode_usize(*n),
178            Number::Isize(n) => encoder.encode_isize(*n),
179            Number::F32(n) => encoder.encode_f32(*n),
180            Number::F64(n) => encoder.encode_f64(*n),
181        }
182    }
183}
184
185impl Number {
186    /// Get the type hint for the number.
187    pub(crate) fn type_hint(&self) -> NumberHint {
188        match self {
189            Number::U8(_) => NumberHint::U8,
190            Number::U16(_) => NumberHint::U16,
191            Number::U32(_) => NumberHint::U32,
192            Number::U64(_) => NumberHint::U64,
193            Number::U128(_) => NumberHint::U128,
194            Number::I8(_) => NumberHint::I8,
195            Number::I16(_) => NumberHint::I16,
196            Number::I32(_) => NumberHint::I32,
197            Number::I64(_) => NumberHint::I64,
198            Number::I128(_) => NumberHint::I128,
199            Number::Usize(_) => NumberHint::Usize,
200            Number::Isize(_) => NumberHint::Isize,
201            Number::F32(_) => NumberHint::F32,
202            Number::F64(_) => NumberHint::F64,
203        }
204    }
205}
206
207struct AnyVisitor;
208
209#[musli::visitor]
210impl<'de, C: ?Sized + Context> Visitor<'de, C> for AnyVisitor {
211    type Ok = Value;
212    #[cfg(feature = "alloc")]
213    type String = StringVisitor;
214    #[cfg(feature = "alloc")]
215    type Bytes = BytesVisitor;
216    #[cfg(feature = "alloc")]
217    type Number = ValueNumberVisitor;
218
219    #[inline]
220    fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
221        write!(f, "value that can be decoded into dynamic container")
222    }
223
224    #[inline]
225    fn visit_unit(self, _: &C) -> Result<Self::Ok, C::Error> {
226        Ok(Value::Unit)
227    }
228
229    #[inline]
230    fn visit_bool(self, _: &C, value: bool) -> Result<Self::Ok, C::Error> {
231        Ok(Value::Bool(value))
232    }
233
234    #[inline]
235    fn visit_char(self, _: &C, value: char) -> Result<Self::Ok, C::Error> {
236        Ok(Value::Char(value))
237    }
238
239    #[inline]
240    fn visit_u8(self, _: &C, value: u8) -> Result<Self::Ok, C::Error> {
241        Ok(Value::Number(Number::U8(value)))
242    }
243
244    #[inline]
245    fn visit_u16(self, _: &C, value: u16) -> Result<Self::Ok, C::Error> {
246        Ok(Value::Number(Number::U16(value)))
247    }
248
249    #[inline]
250    fn visit_u32(self, _: &C, value: u32) -> Result<Self::Ok, C::Error> {
251        Ok(Value::Number(Number::U32(value)))
252    }
253
254    #[inline]
255    fn visit_u64(self, _: &C, value: u64) -> Result<Self::Ok, C::Error> {
256        Ok(Value::Number(Number::U64(value)))
257    }
258
259    #[inline]
260    fn visit_u128(self, _: &C, value: u128) -> Result<Self::Ok, C::Error> {
261        Ok(Value::Number(Number::U128(value)))
262    }
263
264    #[inline]
265    fn visit_i8(self, _: &C, value: i8) -> Result<Self::Ok, C::Error> {
266        Ok(Value::Number(Number::I8(value)))
267    }
268
269    #[inline]
270    fn visit_i16(self, _: &C, value: i16) -> Result<Self::Ok, C::Error> {
271        Ok(Value::Number(Number::I16(value)))
272    }
273
274    #[inline]
275    fn visit_i32(self, _: &C, value: i32) -> Result<Self::Ok, C::Error> {
276        Ok(Value::Number(Number::I32(value)))
277    }
278
279    #[inline]
280    fn visit_i64(self, _: &C, value: i64) -> Result<Self::Ok, C::Error> {
281        Ok(Value::Number(Number::I64(value)))
282    }
283
284    #[inline]
285    fn visit_i128(self, _: &C, value: i128) -> Result<Self::Ok, C::Error> {
286        Ok(Value::Number(Number::I128(value)))
287    }
288
289    #[inline]
290    fn visit_usize(self, _: &C, value: usize) -> Result<Self::Ok, C::Error> {
291        Ok(Value::Number(Number::Usize(value)))
292    }
293
294    #[inline]
295    fn visit_isize(self, _: &C, value: isize) -> Result<Self::Ok, C::Error> {
296        Ok(Value::Number(Number::Isize(value)))
297    }
298
299    #[inline]
300    fn visit_f32(self, _: &C, value: f32) -> Result<Self::Ok, C::Error> {
301        Ok(Value::Number(Number::F32(value)))
302    }
303
304    #[inline]
305    fn visit_f64(self, _: &C, value: f64) -> Result<Self::Ok, C::Error> {
306        Ok(Value::Number(Number::F64(value)))
307    }
308
309    #[cfg(feature = "alloc")]
310    #[inline]
311    fn visit_option<D>(self, _: &C, decoder: Option<D>) -> Result<Self::Ok, C::Error>
312    where
313        D: Decoder<'de, Cx = C, Error = C::Error>,
314    {
315        match decoder {
316            Some(decoder) => Ok(Value::Option(Some(Box::new(decoder.decode::<Value>()?)))),
317            None => Ok(Value::Option(None)),
318        }
319    }
320
321    #[cfg(feature = "alloc")]
322    #[inline]
323    fn visit_sequence<D>(self, _: &C, seq: &mut D) -> Result<Self::Ok, C::Error>
324    where
325        D: SequenceDecoder<'de, Cx = C>,
326    {
327        let mut out = Vec::with_capacity(seq.size_hint().or_default());
328
329        while let Some(item) = seq.try_next()? {
330            out.push(item);
331        }
332
333        Ok(Value::Sequence(out))
334    }
335
336    #[cfg(feature = "alloc")]
337    #[inline]
338    fn visit_map<D>(self, _: &C, map: &mut D) -> Result<Self::Ok, C::Error>
339    where
340        D: MapDecoder<'de, Cx = C>,
341    {
342        let mut out = Vec::with_capacity(map.size_hint().or_default());
343
344        while let Some(mut entry) = map.decode_entry()? {
345            let first = entry.decode_key()?.decode()?;
346            let second = entry.decode_value()?.decode()?;
347            out.push((first, second));
348        }
349
350        Ok(Value::Map(out))
351    }
352
353    #[cfg(feature = "alloc")]
354    #[inline]
355    fn visit_bytes(self, _: &C, _: SizeHint) -> Result<Self::Bytes, C::Error> {
356        Ok(BytesVisitor)
357    }
358
359    #[cfg(feature = "alloc")]
360    #[inline]
361    fn visit_string(self, _: &C, _: SizeHint) -> Result<Self::String, C::Error> {
362        Ok(StringVisitor)
363    }
364
365    #[cfg(feature = "alloc")]
366    #[inline]
367    fn visit_number(self, _: &C) -> Result<Self::Number, C::Error> {
368        Ok(ValueNumberVisitor)
369    }
370
371    #[cfg(feature = "alloc")]
372    #[inline]
373    fn visit_variant<D>(self, _: &C, variant: &mut D) -> Result<Self::Ok, C::Error>
374    where
375        D: VariantDecoder<'de, Cx = C>,
376    {
377        let first = variant.decode_tag()?.decode()?;
378        let second = variant.decode_value()?.decode()?;
379        Ok(Value::Variant(Box::new((first, second))))
380    }
381}
382
383impl<'de, M> Decode<'de, M> for Value {
384    #[inline]
385    fn decode<D>(_: &D::Cx, decoder: D) -> Result<Self, D::Error>
386    where
387        D: Decoder<'de, Mode = M>,
388    {
389        decoder.decode_any(AnyVisitor)
390    }
391}
392
393#[cfg(feature = "alloc")]
394struct BytesVisitor;
395
396#[cfg(feature = "alloc")]
397impl<'de, C: ?Sized + Context> ValueVisitor<'de, C, [u8]> for BytesVisitor {
398    type Ok = Value;
399
400    #[inline]
401    fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
402        write!(f, "bytes")
403    }
404
405    #[cfg(feature = "alloc")]
406    #[inline]
407    fn visit_owned(self, _: &C, bytes: Vec<u8>) -> Result<Self::Ok, C::Error> {
408        Ok(Value::Bytes(bytes))
409    }
410
411    #[inline]
412    fn visit_ref(self, _: &C, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
413        Ok(Value::Bytes(bytes.to_vec()))
414    }
415}
416
417#[cfg(feature = "alloc")]
418struct StringVisitor;
419
420#[cfg(feature = "alloc")]
421impl<'de, C: ?Sized + Context> ValueVisitor<'de, C, str> for StringVisitor {
422    type Ok = Value;
423
424    #[inline]
425    fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
426        write!(f, "bytes")
427    }
428
429    #[inline]
430    fn visit_owned(self, _: &C, string: String) -> Result<Self::Ok, C::Error> {
431        Ok(Value::String(string))
432    }
433
434    #[inline]
435    fn visit_ref(self, _: &C, string: &str) -> Result<Self::Ok, C::Error> {
436        Ok(Value::String(string.to_owned()))
437    }
438}
439
440struct ValueNumberVisitor;
441
442impl<'de, C: ?Sized + Context> NumberVisitor<'de, C> for ValueNumberVisitor {
443    type Ok = Value;
444
445    #[inline]
446    fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
447        write!(f, "any supported number")
448    }
449
450    #[inline]
451    fn visit_u8(self, _: &C, value: u8) -> Result<Self::Ok, C::Error> {
452        Ok(Value::Number(Number::U8(value)))
453    }
454
455    #[inline]
456    fn visit_u16(self, _: &C, value: u16) -> Result<Self::Ok, C::Error> {
457        Ok(Value::Number(Number::U16(value)))
458    }
459
460    #[inline]
461    fn visit_u32(self, _: &C, value: u32) -> Result<Self::Ok, C::Error> {
462        Ok(Value::Number(Number::U32(value)))
463    }
464
465    #[inline]
466    fn visit_u64(self, _: &C, value: u64) -> Result<Self::Ok, C::Error> {
467        Ok(Value::Number(Number::U64(value)))
468    }
469
470    #[inline]
471    fn visit_u128(self, _: &C, value: u128) -> Result<Self::Ok, C::Error> {
472        Ok(Value::Number(Number::U128(value)))
473    }
474
475    #[inline]
476    fn visit_i8(self, _: &C, value: i8) -> Result<Self::Ok, C::Error> {
477        Ok(Value::Number(Number::I8(value)))
478    }
479
480    #[inline]
481    fn visit_i16(self, _: &C, value: i16) -> Result<Self::Ok, C::Error> {
482        Ok(Value::Number(Number::I16(value)))
483    }
484
485    #[inline]
486    fn visit_i32(self, _: &C, value: i32) -> Result<Self::Ok, C::Error> {
487        Ok(Value::Number(Number::I32(value)))
488    }
489
490    #[inline]
491    fn visit_i64(self, _: &C, value: i64) -> Result<Self::Ok, C::Error> {
492        Ok(Value::Number(Number::I64(value)))
493    }
494
495    #[inline]
496    fn visit_i128(self, _: &C, value: i128) -> Result<Self::Ok, C::Error> {
497        Ok(Value::Number(Number::I128(value)))
498    }
499
500    #[inline]
501    fn visit_f32(self, _: &C, value: f32) -> Result<Self::Ok, C::Error> {
502        Ok(Value::Number(Number::F32(value)))
503    }
504
505    #[inline]
506    fn visit_f64(self, _: &C, value: f64) -> Result<Self::Ok, C::Error> {
507        Ok(Value::Number(Number::F64(value)))
508    }
509
510    #[inline]
511    fn visit_usize(self, _: &C, value: usize) -> Result<Self::Ok, C::Error> {
512        Ok(Value::Number(Number::Usize(value)))
513    }
514
515    #[inline]
516    fn visit_isize(self, _: &C, value: isize) -> Result<Self::Ok, C::Error> {
517        Ok(Value::Number(Number::Isize(value)))
518    }
519}
520
521impl<M> Encode<M> for Value {
522    fn encode<E>(&self, _: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
523    where
524        E: Encoder<Mode = M>,
525    {
526        match self {
527            Value::Unit => encoder.encode_unit(),
528            Value::Bool(b) => encoder.encode_bool(*b),
529            Value::Char(c) => encoder.encode_char(*c),
530            Value::Number(n) => encoder.encode(n),
531            #[cfg(feature = "alloc")]
532            Value::Bytes(bytes) => encoder.encode_bytes(bytes),
533            #[cfg(feature = "alloc")]
534            Value::String(string) => encoder.encode_string(string),
535            #[cfg(feature = "alloc")]
536            Value::Sequence(values) => {
537                use musli::hint::SequenceHint;
538
539                let hint = SequenceHint::with_size(values.len());
540
541                encoder.encode_sequence_fn(&hint, |sequence| {
542                    for value in values {
543                        sequence.encode_next()?.encode(value)?;
544                    }
545
546                    Ok(())
547                })
548            }
549            #[cfg(feature = "alloc")]
550            Value::Map(values) => {
551                use musli::hint::MapHint;
552
553                let hint = MapHint::with_size(values.len());
554
555                encoder.encode_map_fn(&hint, |map| {
556                    for (first, second) in values {
557                        map.insert_entry(first, second)?;
558                    }
559
560                    Ok(())
561                })
562            }
563            #[cfg(feature = "alloc")]
564            Value::Variant(variant) => {
565                let (tag, variant) = &**variant;
566                let encoder = encoder.encode_variant()?;
567                encoder.insert_variant(tag, variant)
568            }
569            #[cfg(feature = "alloc")]
570            Value::Option(option) => match option {
571                Some(value) => encoder.encode_some()?.encode(&**value),
572                None => encoder.encode_none(),
573            },
574        }
575    }
576}
577
578/// Value's [AsDecoder] implementation.
579pub struct AsValueDecoder<'a, const OPT: Options, C: ?Sized> {
580    cx: &'a C,
581    value: Value,
582}
583
584impl<'a, const OPT: Options, C: ?Sized> AsValueDecoder<'a, OPT, C> {
585    /// Construct a new buffered value decoder.
586    #[inline]
587    pub fn new(cx: &'a C, value: Value) -> Self {
588        Self { cx, value }
589    }
590}
591
592impl<'a, const OPT: Options, C: ?Sized + Context> AsDecoder for AsValueDecoder<'a, OPT, C> {
593    type Cx = C;
594    type Decoder<'this> = ValueDecoder<'a, 'this, OPT, C> where Self: 'this;
595
596    #[inline]
597    fn as_decoder(&self) -> Result<Self::Decoder<'_>, C::Error> {
598        Ok(self.value.decoder(self.cx))
599    }
600}