Skip to main content

substrate_data/wire/binary/
decoder_straight.rs

1//! [`Decoder`] step by step, for a schema reading itself
2//! ([`crate::Schema::decode`]): `None` for anything but what
3//! [`crate::Schema::encode`] writes there.
4
5use bumpalo::Bump;
6
7use super::decoder::{F32_BYTES, F64_BYTES, MAP_ENTRY_MIN};
8use super::{Decoder, tag, unzigzag};
9use crate::model::number::int_to_f64;
10
11impl<'b> Decoder<'b> {
12    /// The next tag, if it's `t`: read.
13    fn next_is(&mut self, t: u8) -> Option<()> {
14        (self.b.get(self.i) == Some(&t)).then(|| self.i += 1)
15    }
16
17    /// Whether a null is next: read if it is.
18    pub fn null(&mut self) -> bool {
19        self.next_is(tag::NULL).is_some()
20    }
21
22    /// A bool, if one is next.
23    pub fn bool(&mut self) -> Option<bool> {
24        match *self.b.get(self.i)? {
25            tag::FALSE | tag::TRUE => {
26                self.i += 1;
27                Some(self.b[self.i - 1] == tag::TRUE)
28            }
29            _ => None,
30        }
31    }
32
33    /// An integer, if one is next.
34    pub fn int(&mut self) -> Option<i64> {
35        self.next_is(tag::INT)?;
36        self.varint().ok().map(unzigzag)
37    }
38
39    /// A float — or an int, as a number.
40    pub fn float(&mut self) -> Option<f64> {
41        match *self.b.get(self.i)? {
42            tag::FLOAT => {
43                self.i += 1;
44                self.fixed().ok().map(f64::from_le_bytes)
45            }
46            tag::FLOAT32 => {
47                self.i += 1;
48                self.fixed().ok().map(|b| f64::from(f32::from_le_bytes(b)))
49            }
50            tag::INT => self.int().map(int_to_f64),
51            _ => None,
52        }
53    }
54
55    /// A string, if one is next.
56    pub fn str(&mut self) -> Option<&'b str> {
57        self.next_is(tag::STR)?;
58        self.string().ok()
59    }
60
61    /// Bytes, if they're next.
62    pub fn bytes(&mut self) -> Option<&'b [u8]> {
63        self.next_is(tag::BYTES)?;
64        self.length_bytes().ok()
65    }
66
67    /// A list next: how many values; [`Decoder::leave`] after them.
68    pub fn list(&mut self) -> Option<usize> {
69        self.next_is(tag::LIST)?;
70        let n = self.count(1).ok()?;
71        self.deeper().ok()?;
72        Some(n)
73    }
74
75    /// A packed list of ints next ([`Decoder::packed_int`] each): how many.
76    pub fn ints(&mut self) -> Option<usize> {
77        self.next_is(tag::INTS)?;
78        self.count(1).ok()
79    }
80
81    /// A stream next: its body (count and values, strings its own).
82    pub fn stream(&mut self) -> Option<&'b [u8]> {
83        self.next_is(tag::STREAM)?;
84        self.stream_body().ok()
85    }
86
87    /// What's left to read.
88    pub(crate) fn rest(&self) -> &'b [u8] {
89        &self.b[self.i..]
90    }
91
92    /// A stream body's count, first thing in it.
93    pub(crate) fn stream_count(&mut self) -> Option<usize> {
94        self.count(1).ok()
95    }
96
97    /// A packed list of floats next: each one.
98    /// (Written narrow when they fit: widened back.)
99    pub fn floats(&mut self) -> Option<Vec<f64>> {
100        if self.next_is(tag::FLOATS32).is_some() {
101            return Some(crate::frame::floats::widen(
102                self.packed_floats::<F32_BYTES>()
103                    .ok()?
104                    .as_slice()
105                    .as_flattened(),
106            ));
107        }
108        self.next_is(tag::FLOATS)?;
109        Some(
110            self.packed_floats::<F64_BYTES>()
111                .ok()?
112                .map(|f| f64::from_le_bytes(*f))
113                .collect(),
114        )
115    }
116
117    /// A packed list of 32-bit floats next: each one.
118    pub fn floats32(&mut self) -> Option<Vec<f32>> {
119        self.next_is(tag::FLOATS32)?;
120        Some(
121            self.packed_floats::<F32_BYTES>()
122                .ok()?
123                .map(|f| f32::from_le_bytes(*f))
124                .collect(),
125        )
126    }
127
128    /// One int of a packed list.
129    pub fn packed_int(&mut self) -> Option<i64> {
130        self.varint().ok().map(unzigzag)
131    }
132
133    /// A map next: how many entries, each a [`Decoder::key`] and a value;
134    /// [`Decoder::leave`] after them.
135    pub fn map(&mut self) -> Option<usize> {
136        self.next_is(tag::MAP)?;
137        let n = self.count(MAP_ENTRY_MIN).ok()?;
138        self.deeper().ok()?;
139        Some(n)
140    }
141
142    /// The end of a list or map.
143    pub fn leave(&mut self) {
144        self.depth = self.depth.saturating_sub(1);
145    }
146
147    /// A map's next key.
148    pub fn key(&mut self) -> Option<&'b str> {
149        self.string().ok()
150    }
151
152    /// The next value, read and left (its strings still join the table).
153    pub fn skip(&mut self) -> Option<()> {
154        let arena = Bump::new();
155        self.value_ref(&arena).ok().map(drop)
156    }
157}