flow_value/
bincode_impl.rs1use std::borrow::Cow;
2
3use crate::{Value, value_type::Variant};
4use bincode::{
5 Decode, Encode,
6 config::standard,
7 de::Decoder,
8 enc::Encoder,
9 error::{DecodeError, EncodeError},
10};
11use rust_decimal::Decimal;
12
13pub struct MapBincode<'a>(pub Cow<'a, crate::Map>);
14
15impl<'a> From<&'a crate::Map> for MapBincode<'a> {
16 fn from(value: &'a crate::Map) -> Self {
17 Self(Cow::Borrowed(value))
18 }
19}
20
21impl<'a> From<crate::Map> for MapBincode<'a> {
22 fn from(value: crate::Map) -> Self {
23 Self(Cow::Owned(value))
24 }
25}
26
27impl<'a, C> Decode<C> for MapBincode<'a> {
28 fn decode<D: Decoder<Context = C>>(d: &mut D) -> Result<Self, DecodeError> {
29 let len = decode_slice_len(d)?;
30 d.claim_container_read::<(String, Value)>(len)?;
31
32 let mut map = crate::Map::with_capacity(len);
33
34 for _ in 0..len {
35 d.unclaim_bytes_read(core::mem::size_of::<(String, Value)>());
36 let key = String::decode(d)?;
37 let value = Value::decode(d)?;
38 map.insert(key, value);
39 }
40
41 Ok(Self(Cow::Owned(map)))
42 }
43}
44
45impl<'a> Encode for MapBincode<'a> {
46 fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), EncodeError> {
47 (self.0.len() as u64).encode(e)?;
48
49 for (k, v) in self.0.iter() {
50 k.encode(e)?;
51 v.encode(e)?;
52 }
53
54 Ok(())
55 }
56}
57
58pub fn map_to_bincode(map: &crate::Map) -> Result<Vec<u8>, EncodeError> {
59 bincode::encode_to_vec(MapBincode::from(map), standard())
60}
61
62fn decode_slice_len<C, D: Decoder<Context = C>>(d: &mut D) -> Result<usize, DecodeError> {
63 let v = u64::decode(d)?;
64
65 v.try_into().map_err(|_| DecodeError::OutsideUsizeRange(v))
66}
67
68pub fn map_from_bincode(data: &[u8]) -> Result<crate::Map, DecodeError> {
69 Ok(
70 bincode::decode_from_slice::<MapBincode, _>(data, standard())?
71 .0
72 .0
73 .into_owned(),
74 )
75}
76
77impl Encode for Value {
78 fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), EncodeError> {
79 (self.kind() as u8).encode(e)?;
80 match self {
81 crate::Value::Null => {}
82 crate::Value::String(x) => x.encode(e)?,
83 crate::Value::Bool(x) => x.encode(e)?,
84 crate::Value::U64(x) => x.encode(e)?,
85 crate::Value::I64(x) => x.encode(e)?,
86 crate::Value::F64(x) => x.encode(e)?,
87 crate::Value::Decimal(x) => x.serialize().encode(e)?,
88 crate::Value::U128(x) => x.encode(e)?,
89 crate::Value::I128(x) => x.encode(e)?,
90 crate::Value::B32(x) => x.encode(e)?,
91 crate::Value::B64(x) => x.encode(e)?,
92 crate::Value::Bytes(x) => x.encode(e)?,
93 crate::Value::Array(x) => x.encode(e)?,
94 crate::Value::Map(x) => MapBincode::from(x).encode(e)?,
95 }
96 Ok(())
97 }
98}
99
100impl<C> Decode<C> for crate::Value {
101 fn decode<D: Decoder<Context = C>>(d: &mut D) -> Result<Self, DecodeError> {
102 let kind_num = u8::decode(d)?;
103 let kind =
104 Variant::try_from(kind_num as u32).map_err(|_| DecodeError::UnexpectedVariant {
105 type_name: "Value",
106 allowed: &bincode::error::AllowedEnumVariants::Range {
107 min: Variant::MIN,
108 max: Variant::MAX,
109 },
110 found: kind_num as u32,
111 })?;
112 Ok(match kind {
113 Variant::Null => Value::Null,
114 Variant::String => Value::String(<_>::decode(d)?),
115 Variant::Bool => Value::Bool(<_>::decode(d)?),
116 Variant::U64 => Value::U64(<_>::decode(d)?),
117 Variant::I64 => Value::I64(<_>::decode(d)?),
118 Variant::F64 => Value::F64(<_>::decode(d)?),
119 Variant::Decimal => Value::Decimal(Decimal::deserialize(<_>::decode(d)?)),
120 Variant::I128 => Value::I128(<_>::decode(d)?),
121 Variant::U128 => Value::U128(<_>::decode(d)?),
122 Variant::B32 => Value::B32(<_>::decode(d)?),
123 Variant::B64 => Value::B64(<_>::decode(d)?),
124 Variant::Bytes => Value::Bytes(Vec::<u8>::decode(d)?.into()),
125 Variant::Array => Value::Array(<_>::decode(d)?),
126 Variant::Map => Value::Map(MapBincode::decode(d)?.0.into_owned()),
127 })
128 }
129}
130
131impl Value {
132 pub fn to_bincode(&self) -> Result<Vec<u8>, EncodeError> {
133 bincode::encode_to_vec(self, standard())
134 }
135
136 pub fn from_bincode(data: &[u8]) -> Result<Self, DecodeError> {
137 bincode::decode_from_slice(data, standard()).map(|(value, _)| value)
138 }
139}