bin_proto/impls/
option.rs1use bitstream_io::{BitRead, BitWrite, Endianness};
2
3use crate::{BitDecode, BitEncode, Error, Result, Untagged};
4
5impl<Tag, Ctx, T> BitDecode<Ctx, crate::Tag<Tag>> for Option<T>
6where
7 T: BitDecode<Ctx>,
8 Tag: TryInto<bool>,
9{
10 fn decode<R, E>(read: &mut R, ctx: &mut Ctx, tag: crate::Tag<Tag>) -> Result<Self>
11 where
12 R: BitRead,
13 E: Endianness,
14 {
15 if tag.0.try_into().map_err(|_| Error::TagConvert)? {
16 let value = T::decode::<_, E>(read, ctx, ())?;
17 Ok(Some(value))
18 } else {
19 Ok(None)
20 }
21 }
22}
23
24impl<Ctx, T> BitEncode<Ctx, Untagged> for Option<T>
25where
26 T: BitEncode<Ctx>,
27{
28 fn encode<W, E>(&self, write: &mut W, ctx: &mut Ctx, _: Untagged) -> Result<()>
29 where
30 W: BitWrite,
31 E: Endianness,
32 {
33 if let Some(ref value) = *self {
34 value.encode::<_, E>(write, ctx, ())?;
35 }
36 Ok(())
37 }
38}
39
40#[cfg(feature = "prepend-tags")]
41impl<Ctx, T> BitEncode<Ctx> for Option<T>
42where
43 T: BitEncode<Ctx>,
44{
45 fn encode<W, E>(&self, write: &mut W, ctx: &mut Ctx, (): ()) -> Result<()>
46 where
47 W: BitWrite,
48 E: Endianness,
49 {
50 self.is_some().encode::<_, E>(write, ctx, ())?;
51 self.encode::<_, E>(write, ctx, Untagged)
52 }
53}
54
55#[cfg(feature = "prepend-tags")]
56impl<Ctx, T> BitDecode<Ctx> for Option<T>
57where
58 T: BitDecode<Ctx>,
59{
60 fn decode<R, E>(read: &mut R, ctx: &mut Ctx, (): ()) -> Result<Self>
61 where
62 R: BitRead,
63 E: Endianness,
64 {
65 let tag = bool::decode::<_, E>(read, ctx, ())?;
66 Self::decode::<_, E>(read, ctx, crate::Tag(tag))
67 }
68}
69
70#[cfg(test)]
71mod none {
72 use crate::Tag;
73
74 use super::*;
75
76 test_codec!(Option<u8>| Untagged, Tag(false); None => []);
77}
78
79#[cfg(test)]
80mod some {
81 use crate::Tag;
82
83 use super::*;
84
85 test_codec!(Option<u8>| Untagged, Tag(true); Some(1) => [0x01]);
86}
87
88#[cfg(feature = "prepend-tags")]
89test_roundtrip!(Option::<i32>);