tree_buf/internal/types/
nullable.rs1use crate::prelude::*;
2
3#[cfg(feature = "encode")]
4impl<T: Encodable> Encodable for Option<T> {
5 type EncoderArray = NullableEncoder<T::EncoderArray>;
6 fn encode_root<O: EncodeOptions>(&self, stream: &mut EncoderStream<'_, O>) -> RootTypeId {
7 if let Some(value) = self {
8 T::encode_root(value, stream)
9 } else {
10 RootTypeId::Void
11 }
12 }
13}
14
15#[cfg(feature = "decode")]
16impl<T: Decodable> Decodable for Option<T> {
17 type DecoderArray = Option<NullableDecoder<T::DecoderArray>>;
18 fn decode(sticks: DynRootBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
19 profile_method!(decode);
20 match sticks {
21 DynRootBranch::Void => Ok(None),
22 _ => Ok(Some(T::decode(sticks, options)?)),
23 }
24 }
25}
26
27#[cfg(feature = "encode")]
28#[derive(Default)]
29pub struct NullableEncoder<V> {
30 opt: <bool as Encodable>::EncoderArray,
31 value: Option<V>,
32}
33
34#[cfg(feature = "encode")]
35impl<T: Encodable> EncoderArray<Option<T>> for NullableEncoder<T::EncoderArray> {
36 fn buffer_one<'a, 'b: 'a>(&'a mut self, value: &'b Option<T>) {
37 self.opt.buffer_one(&value.is_some());
38 if let Some(value) = value {
39 self.value.get_or_insert_with(T::EncoderArray::default).buffer_one(value);
40 }
41 }
42 fn flush<O: EncodeOptions>(self, stream: &mut EncoderStream<'_, O>) -> ArrayTypeId {
43 profile_method!(flush);
44 let Self { opt, value } = self;
45 if let Some(value) = value {
46 stream.encode_with_id(|stream| opt.flush(stream));
47 stream.encode_with_id(|stream| value.flush(stream));
48 ArrayTypeId::Nullable
49 } else {
50 ArrayTypeId::Void
51 }
52 }
53}
54
55#[cfg(feature = "decode")]
56pub struct NullableDecoder<T> {
57 opts: <bool as Decodable>::DecoderArray,
58 values: T,
59}
60
61#[cfg(feature = "decode")]
62impl<T: DecoderArray> DecoderArray for Option<NullableDecoder<T>> {
63 type Decode = Option<T::Decode>;
64 type Error = T::Error;
65 fn new(sticks: DynArrayBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
66 profile_method!(new);
67
68 match sticks {
69 DynArrayBranch::Nullable { opt, values } => {
70 let (opts, values) = parallel(|| <bool as Decodable>::DecoderArray::new(*opt, options), || T::new(*values, options), options);
71 let opts = opts?;
72 let values = values?;
73 Ok(Some(NullableDecoder { opts, values }))
74 }
75 DynArrayBranch::Void => Ok(None),
76 _ => Err(DecodeError::SchemaMismatch),
77 }
78 }
79 fn decode_next(&mut self) -> Result<Self::Decode, Self::Error> {
80 Ok(if let Some(inner) = self {
81 if inner.opts.decode_next_infallible() {
82 Some(inner.values.decode_next()?)
83 } else {
84 None
85 }
86 } else {
87 None
88 })
89 }
90}