sbor/codec/
option.rs

1use crate::constants::*;
2use crate::prelude::indexmap;
3use crate::value_kind::*;
4use crate::*;
5
6categorize_generic!(Option<T>, <T>, ValueKind::Enum);
7
8impl<X: CustomValueKind, E: Encoder<X>, T: Encode<X, E>> Encode<X, E> for Option<T> {
9    #[inline]
10    fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
11        encoder.write_value_kind(Self::value_kind())
12    }
13
14    #[inline]
15    fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
16        match self {
17            Some(v) => {
18                encoder.write_discriminator(OPTION_VARIANT_SOME)?;
19                encoder.write_size(1)?;
20                encoder.encode(v)?;
21            }
22            None => {
23                encoder.write_discriminator(OPTION_VARIANT_NONE)?;
24                encoder.write_size(0)?;
25            }
26        }
27        Ok(())
28    }
29}
30
31impl<X: CustomValueKind, D: Decoder<X>, T: Decode<X, D>> Decode<X, D> for Option<T> {
32    #[inline]
33    fn decode_body_with_value_kind(
34        decoder: &mut D,
35        value_kind: ValueKind<X>,
36    ) -> Result<Self, DecodeError> {
37        decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
38        let discriminator = decoder.read_discriminator()?;
39
40        match discriminator {
41            OPTION_VARIANT_NONE => {
42                decoder.read_and_check_size(0)?;
43                Ok(None)
44            }
45            OPTION_VARIANT_SOME => {
46                decoder.read_and_check_size(1)?;
47                Ok(Some(decoder.decode()?))
48            }
49            _ => Err(DecodeError::UnknownDiscriminator(discriminator)),
50        }
51    }
52}
53
54impl<C: CustomTypeKind<RustTypeId>, T: Describe<C>> Describe<C> for Option<T> {
55    const TYPE_ID: RustTypeId = RustTypeId::novel("Option", &[T::TYPE_ID]);
56
57    fn type_data() -> TypeData<C, RustTypeId> {
58        #[allow(unused_imports)]
59        use crate::rust::borrow::ToOwned;
60        TypeData::enum_variants(
61            "Option",
62            indexmap![
63                OPTION_VARIANT_NONE => TypeData::no_child_names(TypeKind::Tuple {field_types: crate::rust::vec![]}, "None"),
64                OPTION_VARIANT_SOME => TypeData::no_child_names(TypeKind::Tuple {field_types: crate::rust::vec![T::TYPE_ID]}, "Some"),
65            ],
66        )
67    }
68
69    fn add_all_dependencies(aggregator: &mut TypeAggregator<C>) {
70        aggregator.add_child_type_and_descendents::<T>();
71    }
72}