bitcode/derive/
result.rs

1use crate::coder::{Buffer, Decoder, Encoder, View};
2use crate::derive::variant::{VariantDecoder, VariantEncoder};
3use crate::derive::{Decode, Encode};
4use crate::error::Error;
5use alloc::vec::Vec;
6use core::mem::MaybeUninit;
7use core::num::NonZeroUsize;
8
9pub struct ResultEncoder<T: Encode, E: Encode> {
10    variants: VariantEncoder<2>,
11    ok: T::Encoder,
12    err: E::Encoder,
13}
14
15// Can't derive since it would bound T + E: Default.
16impl<T: Encode, E: Encode> Default for ResultEncoder<T, E> {
17    fn default() -> Self {
18        Self {
19            variants: Default::default(),
20            ok: Default::default(),
21            err: Default::default(),
22        }
23    }
24}
25
26impl<T: Encode, E: Encode> Encoder<Result<T, E>> for ResultEncoder<T, E> {
27    #[inline(always)]
28    fn encode(&mut self, t: &Result<T, E>) {
29        self.variants.encode(&(t.is_err() as u8));
30        match t {
31            Ok(t) => {
32                self.ok.reserve(NonZeroUsize::new(1).unwrap());
33                self.ok.encode(t);
34            }
35            Err(t) => {
36                self.err.reserve(NonZeroUsize::new(1).unwrap());
37                self.err.encode(t);
38            }
39        }
40    }
41    // TODO implement encode_vectored if we can avoid lots of code duplication with OptionEncoder.
42}
43
44impl<T: Encode, E: Encode> Buffer for ResultEncoder<T, E> {
45    fn collect_into(&mut self, out: &mut Vec<u8>) {
46        self.variants.collect_into(out);
47        self.ok.collect_into(out);
48        self.err.collect_into(out);
49    }
50
51    fn reserve(&mut self, additional: NonZeroUsize) {
52        self.variants.reserve(additional);
53        // We don't know how many are Ok or Err, so we can't reserve more.
54    }
55}
56
57pub struct ResultDecoder<'a, T: Decode<'a>, E: Decode<'a>> {
58    variants: VariantDecoder<'a, 2, false>,
59    ok: T::Decoder,
60    err: E::Decoder,
61}
62
63// Can't derive since it would bound T: Default.
64impl<'a, T: Decode<'a>, E: Decode<'a>> Default for ResultDecoder<'a, T, E> {
65    fn default() -> Self {
66        Self {
67            variants: Default::default(),
68            ok: Default::default(),
69            err: Default::default(),
70        }
71    }
72}
73
74impl<'a, T: Decode<'a>, E: Decode<'a>> View<'a> for ResultDecoder<'a, T, E> {
75    fn populate(&mut self, input: &mut &'a [u8], length: usize) -> Result<(), Error> {
76        self.variants.populate(input, length)?;
77        self.ok.populate(input, self.variants.length(0))?;
78        self.err.populate(input, self.variants.length(1))
79    }
80}
81
82impl<'a, T: Decode<'a>, E: Decode<'a>> Decoder<'a, Result<T, E>> for ResultDecoder<'a, T, E> {
83    #[inline(always)]
84    fn decode_in_place(&mut self, out: &mut MaybeUninit<Result<T, E>>) {
85        if self.variants.decode() == 0 {
86            out.write(Ok(self.ok.decode()));
87        } else {
88            out.write(Err(self.err.decode()));
89        }
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use alloc::vec::Vec;
96
97    fn bench_data() -> Vec<Result<u32, u8>> {
98        crate::random_data::<(bool, u32, u8)>(1000)
99            .into_iter()
100            .map(|(is_ok, ok, err)| if is_ok { Ok(ok) } else { Err(err) })
101            .collect()
102    }
103    crate::bench_encode_decode!(result_vec: Vec<_>);
104}