1use crate::{
6 types::*,
7 value::{VALUE_WIRE_TYPE_NAME, VALUE_WIRE_VARIANT_LABELS, Value, ValueWireVariant},
8};
9use num_bigint::{BigInt, BigUint, Sign as BigIntSign};
10use serde::{
11 Deserialize, Deserializer,
12 de::{self, EnumAccess, VariantAccess, Visitor},
13};
14use serde_bytes::ByteBuf;
15use std::{fmt, marker::PhantomData};
16
17struct IntBigWire(IntBig);
26
27impl IntBigWire {
28 fn into_inner(self) -> IntBig {
29 self.0
30 }
31}
32
33impl<'de> Deserialize<'de> for IntBigWire {
34 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
35 where
36 D: Deserializer<'de>,
37 {
38 let (sign, limbs): (i8, Vec<u32>) = Deserialize::deserialize(deserializer)?;
39 let sign = match sign {
40 -1 => BigIntSign::Minus,
41 0 => BigIntSign::NoSign,
42 1 => BigIntSign::Plus,
43 _ => return Err(de::Error::custom(format!("invalid IntBig sign {sign}"))),
44 };
45 let magnitude = BigUint::new(limbs);
46
47 Ok(Self(IntBig::from_bigint(BigInt::from_biguint(
48 sign, magnitude,
49 ))))
50 }
51}
52
53struct NatBigWire(NatBig);
62
63impl NatBigWire {
64 fn into_inner(self) -> NatBig {
65 self.0
66 }
67}
68
69impl<'de> Deserialize<'de> for NatBigWire {
70 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
71 where
72 D: Deserializer<'de>,
73 {
74 let limbs: Vec<u32> = Deserialize::deserialize(deserializer)?;
75 Ok(Self(NatBig::from_biguint(BigUint::new(limbs))))
76 }
77}
78
79struct ValueWireVisitor(PhantomData<()>);
87
88impl ValueWireVisitor {
89 fn decode_map_entries<E>(entries: Vec<(Value, Value)>) -> Result<Value, E>
90 where
91 E: de::Error,
92 {
93 Value::from_map(entries).map_err(E::custom)
94 }
95}
96
97impl<'de> Visitor<'de> for ValueWireVisitor {
98 type Value = Value;
99
100 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
101 formatter.write_str("the stable Value enum wire shape")
102 }
103
104 fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
105 where
106 A: EnumAccess<'de>,
107 {
108 let (variant, payload) = data.variant::<String>()?;
109
110 let Some(variant_tag) = ValueWireVariant::from_label(variant.as_str()) else {
111 return Err(de::Error::unknown_variant(
112 variant.as_str(),
113 VALUE_WIRE_VARIANT_LABELS,
114 ));
115 };
116
117 match variant_tag {
118 ValueWireVariant::Account => Ok(Value::Account(payload.newtype_variant()?)),
119 ValueWireVariant::Blob => Ok(Value::Blob(
120 payload.newtype_variant::<ByteBuf>()?.into_vec(),
121 )),
122 ValueWireVariant::Bool => Ok(Value::Bool(payload.newtype_variant()?)),
123 ValueWireVariant::Date => Ok(Value::Date(payload.newtype_variant()?)),
124 ValueWireVariant::Decimal => Ok(Value::Decimal(payload.newtype_variant()?)),
125 ValueWireVariant::Duration => Ok(Value::Duration(payload.newtype_variant()?)),
126 ValueWireVariant::Enum => Ok(Value::Enum(payload.newtype_variant()?)),
127 ValueWireVariant::Float32 => Ok(Value::Float32(payload.newtype_variant()?)),
128 ValueWireVariant::Float64 => Ok(Value::Float64(payload.newtype_variant()?)),
129 ValueWireVariant::Int64 => Ok(Value::Int64(payload.newtype_variant()?)),
130 ValueWireVariant::Int128 => Ok(Value::Int128(payload.newtype_variant()?)),
131 ValueWireVariant::IntBig => Ok(Value::IntBig(
132 payload.newtype_variant::<IntBigWire>()?.into_inner(),
133 )),
134 ValueWireVariant::List => Ok(Value::List(payload.newtype_variant()?)),
135 ValueWireVariant::Map => {
136 let entries = payload.newtype_variant::<Vec<(Value, Value)>>()?;
137 Self::decode_map_entries(entries)
138 }
139 ValueWireVariant::Null => {
140 payload.unit_variant()?;
141 Ok(Value::Null)
142 }
143 ValueWireVariant::Principal => Ok(Value::Principal(payload.newtype_variant()?)),
144 ValueWireVariant::Subaccount => Ok(Value::Subaccount(payload.newtype_variant()?)),
145 ValueWireVariant::Text => Ok(Value::Text(payload.newtype_variant()?)),
146 ValueWireVariant::Timestamp => Ok(Value::Timestamp(payload.newtype_variant()?)),
147 ValueWireVariant::Nat64 => Ok(Value::Nat64(payload.newtype_variant()?)),
148 ValueWireVariant::Nat128 => Ok(Value::Nat128(payload.newtype_variant()?)),
149 ValueWireVariant::NatBig => Ok(Value::NatBig(
150 payload.newtype_variant::<NatBigWire>()?.into_inner(),
151 )),
152 ValueWireVariant::Ulid => Ok(Value::Ulid(payload.newtype_variant()?)),
153 ValueWireVariant::Unit => {
154 payload.unit_variant()?;
155 Ok(Value::Unit)
156 }
157 }
158 }
159}
160
161impl<'de> Deserialize<'de> for Value {
162 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
163 where
164 D: Deserializer<'de>,
165 {
166 deserializer.deserialize_enum(
167 VALUE_WIRE_TYPE_NAME,
168 VALUE_WIRE_VARIANT_LABELS,
169 ValueWireVisitor(PhantomData),
170 )
171 }
172}