Skip to main content

scale_serialization/
value.rs

1use crate::error::Error;
2#[cfg(feature = "json")]
3use crate::prelude::ToString;
4use crate::registry::*;
5use bytes::Buf;
6use core::str;
7use serde::ser::{SerializeMap, SerializeSeq, SerializeTuple, SerializeTupleStruct};
8use serde::Serialize;
9
10/// Compute the byte size of a SCALE-encoded value given its type.
11pub(crate) fn ty_size(registry: &Registry, data: &[u8], ty: TypeId) -> Result<usize, Error> {
12    match registry.resolve(ty).ok_or(Error::TypeNotFound(ty))? {
13        TypeDef::U8 | TypeDef::I8 | TypeDef::Bool => Ok(1),
14        TypeDef::U16 | TypeDef::I16 => Ok(2),
15        TypeDef::U32 | TypeDef::I32 | TypeDef::Char => Ok(4),
16        TypeDef::U64 | TypeDef::I64 => Ok(8),
17        TypeDef::U128 | TypeDef::I128 => Ok(16),
18        TypeDef::Str | TypeDef::Bytes => {
19            let (l, p) = sequence_size(data)?;
20            Ok(l + p)
21        }
22        TypeDef::StructUnit => Ok(0),
23        TypeDef::StructNewType(inner) => ty_size(registry, data, *inner),
24        TypeDef::Struct(fields) => fields.iter().try_fold(0usize, |c, f| {
25            Ok(c + ty_size(registry, data.get(c..).ok_or(Error::Eof)?, f.ty)?)
26        }),
27        TypeDef::StructTuple(tys) | TypeDef::Tuple(tys) => tys.iter().try_fold(0usize, |c, ty| {
28            Ok(c + ty_size(registry, data.get(c..).ok_or(Error::Eof)?, *ty)?)
29        }),
30        TypeDef::Variant(vdef) => {
31            let &idx = data.first().ok_or(Error::Eof)?;
32            let var = vdef.variant(idx)?;
33            match &var.fields {
34                Fields::Unit => Ok(1),
35                Fields::NewType(ty) => {
36                    Ok(1 + ty_size(registry, data.get(1..).ok_or(Error::Eof)?, *ty)?)
37                }
38                Fields::Tuple(tys) => tys.iter().try_fold(1usize, |c, ty| {
39                    Ok(c + ty_size(registry, data.get(c..).ok_or(Error::Eof)?, *ty)?)
40                }),
41                Fields::Struct(fields) => fields.iter().try_fold(1usize, |c, f| {
42                    Ok(c + ty_size(registry, data.get(c..).ok_or(Error::Eof)?, f.ty)?)
43                }),
44            }
45        }
46        TypeDef::Sequence(ty_id) => {
47            let (len, prefix_size) = sequence_size(data)?;
48            (0..len).try_fold(prefix_size, |c, _| {
49                Ok(c + ty_size(registry, data.get(c..).ok_or(Error::Eof)?, *ty_id)?)
50            })
51        }
52        TypeDef::Array(ty_id, len) => {
53            let element_size = ty_size(registry, data, *ty_id)?;
54            element_size.checked_mul(*len as usize).ok_or(Error::Eof)
55        }
56        TypeDef::Map(ty_k, ty_v) => {
57            let (len, prefix_size) = sequence_size(data)?;
58            (0..len).try_fold(prefix_size, |c, _| {
59                let d = data.get(c..).ok_or(Error::Eof)?;
60                let k = ty_size(registry, d, *ty_k)?;
61                let v = ty_size(registry, d.get(k..).ok_or(Error::Eof)?, *ty_v)?;
62                Ok(c + k + v)
63            })
64        }
65        TypeDef::Compact(_) => compact_size(data),
66        TypeDef::BitSequence(_, _) => {
67            let (bit_len, prefix_size) = sequence_size(data)?;
68            Ok(prefix_size + bit_len.div_ceil(8))
69        }
70    }
71}
72
73/// A container for SCALE encoded data that can serialize types directly
74/// with the help of a type registry and without using an intermediate representation.
75pub struct Value<'a> {
76    pub(crate) data: &'a [u8],
77    pub(crate) ty_id: TypeId,
78    pub(crate) registry: &'a Registry,
79}
80
81impl<'a> Value<'a> {
82    /// Wrap raw SCALE-encoded `data` as a typed value.
83    #[must_use]
84    pub fn new(data: &'a [u8], ty_id: TypeId, registry: &'a Registry) -> Self {
85        Value {
86            data,
87            ty_id,
88            registry,
89        }
90    }
91
92    /// The underlying type definition.
93    #[inline]
94    pub fn ty(&self) -> Option<&'a TypeDef> {
95        self.registry.resolve(self.ty_id)
96    }
97
98    /// Byte length of this value's SCALE encoding.
99    pub fn size(&self) -> Result<usize, Error> {
100        ty_size(self.registry, self.data, self.ty_id)
101    }
102
103    fn cursor(&self) -> Cursor<'a> {
104        Cursor::new(self.data, self.registry)
105    }
106
107    // primitive extraction
108
109    fn read_le<const N: usize>(&self) -> Option<[u8; N]> {
110        self.data.get(..N)?.try_into().ok()
111    }
112
113    pub fn as_u8(&self) -> Option<u8> {
114        matches!(self.ty()?, TypeDef::U8).then(|| ())?;
115        self.data.first().copied()
116    }
117    pub fn as_u16(&self) -> Option<u16> {
118        matches!(self.ty()?, TypeDef::U16).then(|| ())?;
119        Some(u16::from_le_bytes(self.read_le()?))
120    }
121    pub fn as_u32(&self) -> Option<u32> {
122        matches!(self.ty()?, TypeDef::U32).then(|| ())?;
123        Some(u32::from_le_bytes(self.read_le()?))
124    }
125    pub fn as_u64(&self) -> Option<u64> {
126        matches!(self.ty()?, TypeDef::U64).then(|| ())?;
127        Some(u64::from_le_bytes(self.read_le()?))
128    }
129    pub fn as_u128(&self) -> Option<u128> {
130        matches!(self.ty()?, TypeDef::U128).then(|| ())?;
131        Some(u128::from_le_bytes(self.read_le()?))
132    }
133    pub fn as_i8(&self) -> Option<i8> {
134        matches!(self.ty()?, TypeDef::I8).then(|| ())?;
135        self.data.first().map(|&b| b as i8)
136    }
137    pub fn as_i16(&self) -> Option<i16> {
138        matches!(self.ty()?, TypeDef::I16).then(|| ())?;
139        Some(i16::from_le_bytes(self.read_le()?))
140    }
141    pub fn as_i32(&self) -> Option<i32> {
142        matches!(self.ty()?, TypeDef::I32).then(|| ())?;
143        Some(i32::from_le_bytes(self.read_le()?))
144    }
145    pub fn as_i64(&self) -> Option<i64> {
146        matches!(self.ty()?, TypeDef::I64).then(|| ())?;
147        Some(i64::from_le_bytes(self.read_le()?))
148    }
149    pub fn as_i128(&self) -> Option<i128> {
150        matches!(self.ty()?, TypeDef::I128).then(|| ())?;
151        Some(i128::from_le_bytes(self.read_le()?))
152    }
153    pub fn as_bool(&self) -> Option<bool> {
154        matches!(self.ty()?, TypeDef::Bool).then(|| ())?;
155        self.data.first().map(|&b| b != 0)
156    }
157
158    pub fn as_char(&self) -> Option<char> {
159        if !matches!(self.ty()?, TypeDef::Char) {
160            return None;
161        }
162        char::from_u32(u32::from_le_bytes(self.read_le()?))
163    }
164
165    pub fn as_str(&self) -> Option<&'a str> {
166        if !matches!(self.ty()?, TypeDef::Str) {
167            return None;
168        }
169        let (len, prefix) = sequence_size(self.data).ok()?;
170        str::from_utf8(self.data.get(prefix..prefix + len)?).ok()
171    }
172
173    // type predicates
174
175    pub fn is_u8(&self) -> bool {
176        matches!(self.ty(), Some(TypeDef::U8))
177    }
178    pub fn is_u16(&self) -> bool {
179        matches!(self.ty(), Some(TypeDef::U16))
180    }
181    pub fn is_u32(&self) -> bool {
182        matches!(self.ty(), Some(TypeDef::U32))
183    }
184    pub fn is_u64(&self) -> bool {
185        matches!(self.ty(), Some(TypeDef::U64))
186    }
187    pub fn is_u128(&self) -> bool {
188        matches!(self.ty(), Some(TypeDef::U128))
189    }
190    pub fn is_i8(&self) -> bool {
191        matches!(self.ty(), Some(TypeDef::I8))
192    }
193    pub fn is_i16(&self) -> bool {
194        matches!(self.ty(), Some(TypeDef::I16))
195    }
196    pub fn is_i32(&self) -> bool {
197        matches!(self.ty(), Some(TypeDef::I32))
198    }
199    pub fn is_i64(&self) -> bool {
200        matches!(self.ty(), Some(TypeDef::I64))
201    }
202    pub fn is_i128(&self) -> bool {
203        matches!(self.ty(), Some(TypeDef::I128))
204    }
205    pub fn is_bool(&self) -> bool {
206        matches!(self.ty(), Some(TypeDef::Bool))
207    }
208    pub fn is_char(&self) -> bool {
209        matches!(self.ty(), Some(TypeDef::Char))
210    }
211    pub fn is_string(&self) -> bool {
212        matches!(self.ty(), Some(TypeDef::Str))
213    }
214    pub fn is_sequence(&self) -> bool {
215        matches!(self.ty(), Some(TypeDef::Sequence(_)))
216    }
217    pub fn is_array(&self) -> bool {
218        matches!(self.ty(), Some(TypeDef::Array(..)))
219    }
220    pub fn is_tuple(&self) -> bool {
221        matches!(self.ty(), Some(TypeDef::Tuple(_)))
222    }
223    pub fn is_compact(&self) -> bool {
224        matches!(self.ty(), Some(TypeDef::Compact(_)))
225    }
226    pub fn is_variant(&self) -> bool {
227        matches!(self.ty(), Some(TypeDef::Variant(_)))
228    }
229    pub fn is_composite(&self) -> bool {
230        matches!(
231            self.ty(),
232            Some(
233                TypeDef::Struct(_)
234                    | TypeDef::StructUnit
235                    | TypeDef::StructNewType(_)
236                    | TypeDef::StructTuple(_)
237            )
238        )
239    }
240
241    // sequence access
242
243    pub fn sequence_len(&self) -> Option<usize> {
244        matches!(self.ty()?, TypeDef::Sequence(_))
245            .then(|| sequence_size(self.data).ok().map(|(len, _)| len))?
246    }
247
248    pub fn sequence_get(&self, index: usize) -> Option<Value<'a>> {
249        let TypeDef::Sequence(inner_ty) = self.ty()? else {
250            return None;
251        };
252        let (len, prefix_size) = sequence_size(self.data).ok()?;
253        if index >= len {
254            return None;
255        }
256        let ty_id = *inner_ty;
257        let mut cursor = Cursor::new(&self.data[prefix_size..], self.registry);
258        for _ in 0..index {
259            cursor.next_value(ty_id).ok()?;
260        }
261        cursor.next_value(ty_id).ok()
262    }
263
264    pub fn sequence_iter(&self) -> Option<SeqIter<'a>> {
265        let TypeDef::Sequence(inner_ty) = self.ty()? else {
266            return None;
267        };
268        let (len, prefix_size) = sequence_size(self.data).ok()?;
269        Some(SeqIter {
270            cursor: Cursor::new(&self.data[prefix_size..], self.registry),
271            ty_id: *inner_ty,
272            remaining: len,
273        })
274    }
275
276    // array access
277
278    pub fn array_len(&self) -> Option<u32> {
279        let TypeDef::Array(_, len) = self.ty()? else {
280            return None;
281        };
282        Some(*len)
283    }
284
285    pub fn array_get(&self, index: u32) -> Option<Value<'a>> {
286        let TypeDef::Array(ty_id, len) = self.ty()? else {
287            return None;
288        };
289        if index >= *len {
290            return None;
291        }
292        let ty_id = *ty_id;
293        let element_size = ty_size(self.registry, self.data, ty_id).ok()?;
294        let start = (index as usize).checked_mul(element_size)?;
295        let end = start.checked_add(element_size)?;
296        (end <= self.data.len()).then(|| Value::new(&self.data[start..end], ty_id, self.registry))
297    }
298
299    // struct/composite access
300
301    pub fn field_count(&self) -> Option<usize> {
302        let TypeDef::Struct(fields) = self.ty()? else {
303            return None;
304        };
305        Some(fields.len())
306    }
307
308    pub fn field_at(&self, index: usize) -> Option<Value<'a>> {
309        let TypeDef::Struct(fields) = self.ty()? else {
310            return None;
311        };
312        let field = fields.get(index)?;
313        let mut offset = 0;
314        for f in fields.iter().take(index) {
315            offset += ty_size(self.registry, self.data.get(offset..)?, f.ty).ok()?;
316        }
317        let size = ty_size(self.registry, self.data.get(offset..)?, field.ty).ok()?;
318        Some(Value::new(
319            &self.data[offset..offset + size],
320            field.ty,
321            self.registry,
322        ))
323    }
324
325    pub fn field(&self, name: &str) -> Option<Value<'a>> {
326        let TypeDef::Struct(fields) = self.ty()? else {
327            return None;
328        };
329        let mut offset = 0;
330        for f in fields {
331            let size = ty_size(self.registry, self.data.get(offset..)?, f.ty).ok()?;
332            if f.name == name {
333                return Some(Value::new(
334                    &self.data[offset..offset + size],
335                    f.ty,
336                    self.registry,
337                ));
338            }
339            offset += size;
340        }
341        None
342    }
343
344    pub fn fields_iter(&self) -> Option<FieldIter<'a>> {
345        let TypeDef::Struct(fields) = self.ty()? else {
346            return None;
347        };
348        Some(FieldIter {
349            cursor: self.cursor(),
350            fields: fields.as_slice(),
351            index: 0,
352        })
353    }
354
355    // tuple access
356
357    pub fn tuple_len(&self) -> Option<usize> {
358        let TypeDef::Tuple(tys) = self.ty()? else {
359            return None;
360        };
361        Some(tys.len())
362    }
363
364    pub fn tuple_get(&self, index: usize) -> Option<Value<'a>> {
365        let TypeDef::Tuple(tys) = self.ty()? else {
366            return None;
367        };
368        let ty_id = *tys.get(index)?;
369        let mut offset = 0;
370        for ty in tys.iter().take(index) {
371            offset += ty_size(self.registry, self.data.get(offset..)?, *ty).ok()?;
372        }
373        let size = ty_size(self.registry, self.data.get(offset..)?, ty_id).ok()?;
374        Some(Value::new(
375            &self.data[offset..offset + size],
376            ty_id,
377            self.registry,
378        ))
379    }
380
381    pub fn tuple_iter(&self) -> Option<TupleIter<'a>> {
382        let TypeDef::Tuple(tys) = self.ty()? else {
383            return None;
384        };
385        Some(TupleIter {
386            cursor: self.cursor(),
387            types: tys.as_slice(),
388            index: 0,
389        })
390    }
391
392    // variant/enum access
393
394    pub fn variant_index(&self) -> Option<u8> {
395        let TypeDef::Variant(_) = self.ty()? else {
396            return None;
397        };
398        self.data.first().copied()
399    }
400
401    pub fn variant_name(&self) -> Option<&str> {
402        let TypeDef::Variant(vdef) = self.ty()? else {
403            return None;
404        };
405        let idx = *self.data.first()?;
406        vdef.variant(idx).ok().map(|v| v.name.as_str())
407    }
408
409    pub fn variant_data(&self) -> Option<Value<'a>> {
410        let TypeDef::Variant(vdef) = self.ty()? else {
411            return None;
412        };
413        let var = vdef.variant(*self.data.first()?).ok()?;
414        let Fields::NewType(ty_id) = &var.fields else {
415            return None;
416        };
417        Some(Value::new(&self.data[1..], *ty_id, self.registry))
418    }
419}
420
421/// A zero-copy cursor over SCALE-encoded bytes that yields [`Value`]s
422/// while advancing through the data.
423pub struct Cursor<'a> {
424    pub(crate) data: &'a [u8],
425    pub(crate) registry: &'a Registry,
426}
427
428impl<'a> Cursor<'a> {
429    #[must_use]
430    pub fn new(data: &'a [u8], registry: &'a Registry) -> Self {
431        Cursor { data, registry }
432    }
433
434    /// Decode the next value of type `ty_id`, advancing past its bytes.
435    pub fn next_value(&mut self, ty_id: TypeId) -> Result<Value<'a>, Error> {
436        let size = ty_size(self.registry, self.data, ty_id)?;
437        let (chunk, rest) = self.data.split_at(size);
438        self.data = rest;
439        Ok(Value {
440            data: chunk,
441            ty_id,
442            registry: self.registry,
443        })
444    }
445
446    /// Bytes not yet consumed.
447    #[must_use]
448    pub fn remaining(&self) -> &'a [u8] {
449        self.data
450    }
451}
452
453/// Iterator over elements of a SCALE-encoded sequence.
454pub struct SeqIter<'a> {
455    cursor: Cursor<'a>,
456    ty_id: TypeId,
457    remaining: usize,
458}
459
460impl<'a> Iterator for SeqIter<'a> {
461    type Item = Value<'a>;
462
463    fn next(&mut self) -> Option<Self::Item> {
464        (self.remaining > 0).then(|| {
465            self.remaining -= 1;
466            self.cursor.next_value(self.ty_id).ok()
467        })?
468    }
469
470    #[inline]
471    fn size_hint(&self) -> (usize, Option<usize>) {
472        (self.remaining, Some(self.remaining))
473    }
474}
475
476impl ExactSizeIterator for SeqIter<'_> {}
477
478/// Iterator over named fields of a SCALE-encoded struct.
479pub struct FieldIter<'a> {
480    cursor: Cursor<'a>,
481    fields: &'a [Field],
482    index: usize,
483}
484
485impl<'a> Iterator for FieldIter<'a> {
486    type Item = (&'a str, Value<'a>);
487
488    fn next(&mut self) -> Option<Self::Item> {
489        let field = self.fields.get(self.index)?;
490        self.index += 1;
491        let val = self.cursor.next_value(field.ty).ok()?;
492        Some((&field.name, val))
493    }
494
495    #[inline]
496    fn size_hint(&self) -> (usize, Option<usize>) {
497        let rem = self.fields.len() - self.index;
498        (rem, Some(rem))
499    }
500}
501
502impl ExactSizeIterator for FieldIter<'_> {}
503
504/// Iterator over elements of a SCALE-encoded tuple.
505pub struct TupleIter<'a> {
506    cursor: Cursor<'a>,
507    types: &'a [TypeId],
508    index: usize,
509}
510
511impl<'a> Iterator for TupleIter<'a> {
512    type Item = Value<'a>;
513
514    fn next(&mut self) -> Option<Self::Item> {
515        let &ty_id = self.types.get(self.index)?;
516        self.index += 1;
517        self.cursor.next_value(ty_id).ok()
518    }
519
520    #[inline]
521    fn size_hint(&self) -> (usize, Option<usize>) {
522        let rem = self.types.len() - self.index;
523        (rem, Some(rem))
524    }
525}
526
527impl ExactSizeIterator for TupleIter<'_> {}
528
529// Serialize impl
530
531use serde::ser::Error as _;
532
533impl Serialize for Value<'_> {
534    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
535    where
536        S: serde::Serializer,
537    {
538        let mut data: &[u8] = self.data;
539        let ty = self
540            .registry
541            .resolve(self.ty_id)
542            .ok_or_else(|| S::Error::custom(Error::TypeNotFound(self.ty_id)))?;
543
544        match ty {
545            TypeDef::Bool => ser.serialize_bool(data.get_u8() != 0),
546            TypeDef::U8 => ser.serialize_u8(data.get_u8()),
547            TypeDef::U16 => ser.serialize_u16(data.get_u16_le()),
548            TypeDef::U32 => ser.serialize_u32(data.get_u32_le()),
549            TypeDef::U64 => ser.serialize_u64(data.get_u64_le()),
550            TypeDef::U128 => ser.serialize_u128(data.get_u128_le()),
551            TypeDef::I8 => ser.serialize_i8(data.get_i8()),
552            TypeDef::I16 => ser.serialize_i16(data.get_i16_le()),
553            TypeDef::I32 => ser.serialize_i32(data.get_i32_le()),
554            TypeDef::I64 => ser.serialize_i64(data.get_i64_le()),
555            TypeDef::I128 => ser.serialize_i128(data.get_i128_le()),
556            TypeDef::Compact(_) => {
557                let (v, _) = sequence_size(data).map_err(S::Error::custom)?;
558                ser.serialize_u128(v as u128)
559            }
560            TypeDef::Bytes => {
561                let (_, s) = sequence_size(data).map_err(S::Error::custom)?;
562                data.advance(s);
563                ser.serialize_bytes(data)
564            }
565            TypeDef::Char => {
566                let code = data.get_u32_le();
567                let c = char::from_u32(code)
568                    .ok_or_else(|| S::Error::custom(Error::InvalidChar(code)))?;
569                ser.serialize_char(c)
570            }
571            TypeDef::Str => {
572                let (_, s) = sequence_size(data).map_err(S::Error::custom)?;
573                data.advance(s);
574                let text =
575                    str::from_utf8(data).map_err(|_| S::Error::custom(Error::InvalidUtf8))?;
576                ser.serialize_str(text)
577            }
578            TypeDef::Sequence(ty_id) => {
579                let (len, p_size) = sequence_size(data).map_err(S::Error::custom)?;
580                data.advance(p_size);
581                let mut cursor = Cursor::new(data, self.registry);
582                let mut seq = ser.serialize_seq(Some(len))?;
583                for _ in 0..len {
584                    seq.serialize_element(&cursor.next_value(*ty_id).map_err(S::Error::custom)?)?;
585                }
586                seq.end()
587            }
588            TypeDef::Map(ty_k, ty_v) => {
589                let (len, p_size) = sequence_size(data).map_err(S::Error::custom)?;
590                data.advance(p_size);
591                let mut cursor = Cursor::new(data, self.registry);
592                let mut state = ser.serialize_map(Some(len))?;
593                for _ in 0..len {
594                    let key = cursor.next_value(*ty_k).map_err(S::Error::custom)?;
595                    let val = cursor.next_value(*ty_v).map_err(S::Error::custom)?;
596                    state.serialize_entry(&key, &val)?;
597                }
598                state.end()
599            }
600            TypeDef::Array(ty_id, len) => {
601                let mut cursor = Cursor::new(data, self.registry);
602                let mut state = ser.serialize_tuple(*len as usize)?;
603                for _ in 0..*len {
604                    state
605                        .serialize_element(&cursor.next_value(*ty_id).map_err(S::Error::custom)?)?;
606                }
607                state.end()
608            }
609            TypeDef::Tuple(fields) => {
610                let mut cursor = Cursor::new(data, self.registry);
611                let mut state = ser.serialize_tuple(fields.len())?;
612                for ty_id in fields {
613                    state
614                        .serialize_element(&cursor.next_value(*ty_id).map_err(S::Error::custom)?)?;
615                }
616                state.end()
617            }
618            TypeDef::Struct(fields) => {
619                let mut cursor = Cursor::new(data, self.registry);
620                let mut state = ser.serialize_map(Some(fields.len()))?;
621                for f in fields {
622                    state.serialize_key(&f.name)?;
623                    state.serialize_value(&cursor.next_value(f.ty).map_err(S::Error::custom)?)?;
624                }
625                state.end()
626            }
627            TypeDef::StructUnit => ser.serialize_unit(),
628            TypeDef::StructNewType(ty_id) => {
629                let mut cursor = Cursor::new(data, self.registry);
630                ser.serialize_newtype_struct(
631                    "",
632                    &cursor.next_value(*ty_id).map_err(S::Error::custom)?,
633                )
634            }
635            TypeDef::StructTuple(fields) => {
636                let mut cursor = Cursor::new(data, self.registry);
637                let mut state = ser.serialize_tuple_struct("", fields.len())?;
638                for ty_id in fields {
639                    state.serialize_field(&cursor.next_value(*ty_id).map_err(S::Error::custom)?)?;
640                }
641                state.end()
642            }
643            TypeDef::Variant(vdef) => {
644                if data.is_empty() {
645                    return Err(S::Error::custom(Error::Eof));
646                }
647                let idx = data.get_u8();
648                let var = vdef.variant(idx).map_err(S::Error::custom)?;
649                let is_option = vdef.name == "Option";
650                let mut cursor = Cursor::new(data, self.registry);
651
652                match &var.fields {
653                    Fields::Unit => {
654                        if is_option && var.name == "None" {
655                            ser.serialize_none()
656                        } else {
657                            ser.serialize_str(&var.name)
658                        }
659                    }
660                    Fields::NewType(ty_id) => {
661                        let v = cursor.next_value(*ty_id).map_err(S::Error::custom)?;
662                        if is_option && var.name == "Some" {
663                            ser.serialize_some(&v)
664                        } else {
665                            let mut s = ser.serialize_map(Some(1))?;
666                            s.serialize_key(&var.name)?;
667                            s.serialize_value(&v)?;
668                            s.end()
669                        }
670                    }
671                    Fields::Tuple(tys) => {
672                        let mut s = ser.serialize_map(Some(1))?;
673                        s.serialize_key(&var.name)?;
674                        let vals: Result<alloc::vec::Vec<_>, _> = tys
675                            .iter()
676                            .map(|ty| cursor.next_value(*ty).map_err(S::Error::custom))
677                            .collect();
678                        s.serialize_value(&vals?)?;
679                        s.end()
680                    }
681                    Fields::Struct(fields) => {
682                        let mut s = ser.serialize_map(Some(1))?;
683                        s.serialize_key(&var.name)?;
684                        s.serialize_value(&StructFields(&mut cursor, fields))?;
685                        s.end()
686                    }
687                }
688            }
689            TypeDef::BitSequence(_, _) => {
690                let (bit_len, prefix_size) = sequence_size(data).map_err(S::Error::custom)?;
691                data.advance(prefix_size);
692                let byte_len = bit_len.div_ceil(8);
693                if data.len() < byte_len {
694                    return Err(S::Error::custom(Error::Eof));
695                }
696                ser.serialize_bytes(&data[..byte_len])
697            }
698        }
699    }
700}
701
702/// Helper to serialize variant struct fields as a map without intermediate allocation.
703struct StructFields<'a, 'b>(&'b mut Cursor<'a>, &'a [Field]);
704
705impl Serialize for StructFields<'_, '_> {
706    fn serialize<S: serde::Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
707        // We need &mut access to the cursor, but Serialize takes &self.
708        // Since this is only ever serialized once, we use a cell to get interior mutability.
709        // Actually we can't do that cleanly, fall back to collecting.
710        // TODO: consider a custom Serializer approach to avoid this allocation.
711        let mut data = self.0.remaining();
712        let mut state = ser.serialize_map(Some(self.1.len()))?;
713        for f in self.1 {
714            state.serialize_key(&f.name)?;
715            let size = ty_size(self.0.registry, data, f.ty).map_err(S::Error::custom)?;
716            let (chunk, rest) = data.split_at(size);
717            data = rest;
718            state.serialize_value(&Value::new(chunk, f.ty, self.0.registry))?;
719        }
720        state.end()
721    }
722}
723
724#[inline]
725fn compact_size(data: &[u8]) -> Result<usize, Error> {
726    let &first = data.first().ok_or(Error::Eof)?;
727    match first & 0b11 {
728        0 => Ok(1),
729        1 if data.len() >= 2 => Ok(2),
730        2 if data.len() >= 4 => Ok(4),
731        3 => {
732            let total = 1 + (first >> 2) as usize + 4;
733            (data.len() >= total).then_some(total).ok_or(Error::Eof)
734        }
735        _ => Err(Error::Eof),
736    }
737}
738
739pub(crate) fn sequence_size(data: &[u8]) -> Result<(usize, usize), Error> {
740    let prefix = compact_size(data)?;
741    let len = match prefix {
742        1 => (data[0] >> 2) as usize,
743        2 => ((data[0] as u16 >> 2) | ((data[1] as u16) << 6)) as usize,
744        4 => {
745            (((data[0] as u32) >> 2)
746                | ((data[1] as u32) << 6)
747                | ((data[2] as u32) << 14)
748                | ((data[3] as u32) << 22)) as usize
749        }
750        n => {
751            let byte_count = n - 1;
752            let mut value: u64 = 0;
753            for i in 0..byte_count.min(8) {
754                value |= (data[1 + i] as u64) << (i * 8);
755            }
756            value as usize
757        }
758    };
759    Ok((len, prefix))
760}
761
762impl AsRef<[u8]> for Value<'_> {
763    fn as_ref(&self) -> &[u8] {
764        self.data
765    }
766}
767
768impl core::fmt::Debug for Value<'_> {
769    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
770        write!(
771            f,
772            "Value {{ data: {:?}, type({}): {:?} }}",
773            self.data,
774            self.ty_id,
775            self.ty()
776        )
777    }
778}
779
780#[cfg(all(feature = "json", not(feature = "text")))]
781impl core::fmt::Display for Value<'_> {
782    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
783        let json = serde_json::to_string(self).map_err(|_| core::fmt::Error)?;
784        write!(f, "{}", json)
785    }
786}
787
788#[cfg(feature = "json")]
789impl<'reg> TryFrom<Value<'reg>> for serde_json::Value {
790    type Error = Error;
791
792    fn try_from(val: Value<'reg>) -> Result<Self, Self::Error> {
793        serde_json::value::to_value(val).map_err(|e| Error::Ser(e.to_string()))
794    }
795}