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#[derive(Debug, Clone, PartialEq, PartialOrd)]
29#[non_exhaustive]
30pub enum Value {
31 Unit,
33 Bool(bool),
35 Char(char),
37 Number(Number),
39 #[cfg(feature = "alloc")]
41 Bytes(Vec<u8>),
42 #[cfg(feature = "alloc")]
44 String(String),
45 #[cfg(feature = "alloc")]
47 Sequence(Vec<Value>),
48 #[cfg(feature = "alloc")]
50 Map(Vec<(Value, Value)>),
51 #[cfg(feature = "alloc")]
54 Variant(Box<(Value, Value)>),
55 #[cfg(feature = "alloc")]
57 Option(Option<Box<Value>>),
58}
59
60impl Value {
61 #[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 #[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 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(u8),
108 U16(u16),
110 U32(u32),
112 U64(u64),
114 U128(u128),
116 I8(i8),
118 I16(i16),
120 I32(i32),
122 I64(i64),
124 I128(i128),
126 Usize(usize),
128 Isize(isize),
130 F32(f32),
132 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 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
578pub 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 #[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}