1pub mod daily_withdrawal_limit;
2#[cfg(all(feature = "withdrawals-contract", feature = "system_contracts"))]
3mod document_try_into_asset_unlock_base_transaction_info;
4
5use bincode::{Decode, Encode};
6use serde_repr::{Deserialize_repr, Serialize_repr};
7
8#[cfg(feature = "json-conversion")]
9use crate::serialization::JsonConvertible;
10#[cfg(feature = "value-conversion")]
11use crate::serialization::ValueConvertible;
12
13#[repr(u8)]
14#[derive(
15 Serialize_repr, Deserialize_repr, PartialEq, Eq, Clone, Copy, Debug, Encode, Decode, Default,
16)]
17pub enum Pooling {
18 #[default]
19 Never = 0,
20 IfAvailable = 1,
21 Standard = 2,
22}
23
24#[cfg(feature = "json-conversion")]
25impl JsonConvertible for Pooling {}
26
27#[cfg(feature = "value-conversion")]
28impl ValueConvertible for Pooling {}
29
30pub type WithdrawalTransactionIndex = u64;
32
33pub type WithdrawalTransactionIndexAndBytes = (WithdrawalTransactionIndex, Vec<u8>);
35
36#[cfg(feature = "serde-conversion")]
49pub mod pooling_serde {
50 use super::Pooling;
51 use serde::{Deserializer, Serialize, Serializer};
52
53 pub fn serialize<S: Serializer>(pooling: &Pooling, serializer: S) -> Result<S::Ok, S::Error> {
54 if serializer.is_human_readable() {
55 let name = match pooling {
56 Pooling::Never => "never",
57 Pooling::IfAvailable => "ifAvailable",
58 Pooling::Standard => "standard",
59 };
60 serializer.serialize_str(name)
61 } else {
62 (*pooling as u8).serialize(serializer)
63 }
64 }
65
66 pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Pooling, D::Error> {
74 struct PoolingVisitor;
75
76 impl<'de> serde::de::Visitor<'de> for PoolingVisitor {
77 type Value = Pooling;
78
79 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
80 f.write_str("a Pooling variant: 'never'/'ifAvailable'/'standard' or 0/1/2")
81 }
82
83 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Pooling, E> {
84 match v {
85 "never" | "Never" => Ok(Pooling::Never),
86 "ifAvailable" | "IfAvailable" | "ifavailable" => Ok(Pooling::IfAvailable),
87 "standard" | "Standard" => Ok(Pooling::Standard),
88 other => Err(E::custom(format!(
89 "unknown pooling variant '{}', expected 'never' | 'ifAvailable' | 'standard'",
90 other
91 ))),
92 }
93 }
94
95 fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Pooling, E> {
96 self.visit_str(&v)
97 }
98
99 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Pooling, E> {
100 match v {
101 0 => Ok(Pooling::Never),
102 1 => Ok(Pooling::IfAvailable),
103 2 => Ok(Pooling::Standard),
104 other => Err(E::custom(format!("unknown pooling discriminant {}", other))),
105 }
106 }
107
108 fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Pooling, E> {
109 if v < 0 {
110 return Err(E::custom(format!("negative pooling discriminant {}", v)));
111 }
112 self.visit_u64(v as u64)
113 }
114
115 fn visit_u8<E: serde::de::Error>(self, v: u8) -> Result<Pooling, E> {
116 self.visit_u64(v as u64)
117 }
118 }
119
120 if deserializer.is_human_readable() {
121 deserializer.deserialize_any(PoolingVisitor)
122 } else {
123 deserializer.deserialize_u8(PoolingVisitor)
124 }
125 }
126
127 #[cfg(test)]
128 mod tests {
129 use super::*;
130 use serde::{Deserialize, Serialize};
131
132 #[derive(Serialize, Deserialize, PartialEq, Debug)]
133 struct Wrap(#[serde(with = "super")] Pooling);
134
135 #[test]
136 fn json_emits_camelcase_string() {
137 for (variant, expected) in [
138 (Pooling::Never, "\"never\""),
139 (Pooling::IfAvailable, "\"ifAvailable\""),
140 (Pooling::Standard, "\"standard\""),
141 ] {
142 let json = serde_json::to_string(&Wrap(variant)).expect("serialize");
143 assert_eq!(json, expected);
144 let restored: Wrap = serde_json::from_str(expected).expect("deserialize");
145 assert_eq!(restored, Wrap(variant));
146 }
147 }
148
149 #[test]
150 fn bincode_keeps_u8_discriminant() {
151 for (variant, expected_u8) in [
152 (Pooling::Never, 0),
153 (Pooling::IfAvailable, 1),
154 (Pooling::Standard, 2),
155 ] {
156 let bytes =
157 bincode::serde::encode_to_vec(Wrap(variant), bincode::config::standard())
158 .expect("bincode encode");
159 assert_eq!(bytes.last(), Some(&expected_u8));
160 let (restored, _): (Wrap, usize) =
161 bincode::serde::decode_from_slice(&bytes, bincode::config::standard())
162 .expect("bincode decode");
163 assert_eq!(restored, Wrap(variant));
164 }
165 }
166 }
167}
168
169#[cfg(all(
170 test,
171 feature = "json-conversion",
172 feature = "value-conversion",
173 feature = "serde-conversion"
174))]
175mod json_convertible_tests_pooling {
176 use super::*;
177 use platform_value::platform_value;
178 use serde_json::json;
179
180 #[test]
186 fn json_round_trip_never() {
187 use crate::serialization::JsonConvertible;
188 let original = Pooling::Never;
189 let json = original.to_json().expect("to_json");
190 assert_eq!(json, json!(0));
192 let recovered = Pooling::from_json(json).expect("from_json");
193 assert_eq!(original, recovered);
194 }
195
196 #[test]
197 fn json_round_trip_if_available() {
198 use crate::serialization::JsonConvertible;
199 let original = Pooling::IfAvailable;
200 let json = original.to_json().expect("to_json");
201 assert_eq!(json, json!(1));
202 let recovered = Pooling::from_json(json).expect("from_json");
203 assert_eq!(original, recovered);
204 }
205
206 #[test]
207 fn json_round_trip_standard() {
208 use crate::serialization::JsonConvertible;
209 let original = Pooling::Standard;
210 let json = original.to_json().expect("to_json");
211 assert_eq!(json, json!(2));
212 let recovered = Pooling::from_json(json).expect("from_json");
213 assert_eq!(original, recovered);
214 }
215
216 #[test]
217 fn value_round_trip_never() {
218 use crate::serialization::ValueConvertible;
219 let original = Pooling::Never;
220 let value = original.to_object().expect("to_object");
221 assert_eq!(value, platform_value!(0u8));
223 let recovered = Pooling::from_object(value).expect("from_object");
224 assert_eq!(original, recovered);
225 }
226
227 #[test]
228 fn value_round_trip_if_available() {
229 use crate::serialization::ValueConvertible;
230 let original = Pooling::IfAvailable;
231 let value = original.to_object().expect("to_object");
232 assert_eq!(value, platform_value!(1u8));
233 let recovered = Pooling::from_object(value).expect("from_object");
234 assert_eq!(original, recovered);
235 }
236
237 #[test]
238 fn value_round_trip_standard() {
239 use crate::serialization::ValueConvertible;
240 let original = Pooling::Standard;
241 let value = original.to_object().expect("to_object");
242 assert_eq!(value, platform_value!(2u8));
243 let recovered = Pooling::from_object(value).expect("from_object");
244 assert_eq!(original, recovered);
245 }
246}