1use std::fmt::Display;
2use std::str::FromStr;
3
4use af_sui_types::GasCostSummary;
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use serde_with::{DeserializeAs, DisplayFromStr, SerializeAs, serde_as};
7
8#[serde_as]
13#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Copy)]
14pub struct BigInt<T>(#[serde_as(as = "serde_with::DisplayFromStr")] T)
15where
16 T: Display + FromStr,
17 <T as FromStr>::Err: Display;
18
19impl<T> BigInt<T>
20where
21 T: Display + FromStr,
22 <T as FromStr>::Err: Display,
23{
24 pub fn into_inner(self) -> T {
25 self.0
26 }
27}
28
29impl<T> SerializeAs<T> for BigInt<T>
30where
31 T: Display + FromStr + Copy,
32 <T as FromStr>::Err: Display,
33{
34 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 {
38 Self(*value).serialize(serializer)
39 }
40}
41
42impl<'de, T> DeserializeAs<'de, T> for BigInt<T>
43where
44 T: Display + FromStr + Copy,
45 <T as FromStr>::Err: Display,
46{
47 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
48 where
49 D: Deserializer<'de>,
50 {
51 Ok(*Self::deserialize(deserializer)?)
52 }
53}
54
55impl<T> From<T> for BigInt<T>
56where
57 T: Display + FromStr,
58 <T as FromStr>::Err: Display,
59{
60 fn from(v: T) -> Self {
61 Self(v)
62 }
63}
64
65impl<T> std::ops::Deref for BigInt<T>
66where
67 T: Display + FromStr,
68 <T as FromStr>::Err: Display,
69{
70 type Target = T;
71
72 fn deref(&self) -> &Self::Target {
73 &self.0
74 }
75}
76
77impl<T> Display for BigInt<T>
78where
79 T: Display + FromStr,
80 <T as FromStr>::Err: Display,
81{
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 write!(f, "{}", self.0)
84 }
85}
86
87pub(crate) struct Base64orBase58;
93
94impl<T> SerializeAs<T> for Base64orBase58
95where
96 T: AsRef<[u8]>,
97{
98 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: Serializer,
101 {
102 let encoded_string = af_sui_types::encode_base64_default(value);
103 encoded_string.serialize(serializer)
104 }
105}
106
107impl<'de> DeserializeAs<'de, Vec<u8>> for Base64orBase58 {
108 fn deserialize_as<D>(deserializer: D) -> Result<Vec<u8>, D::Error>
109 where
110 D: Deserializer<'de>,
111 {
112 let s = String::deserialize(deserializer)?;
113
114 af_sui_types::decode_base64_default(&s)
115 .or_else(|_| af_sui_types::encoding::Base58::decode(&s))
116 .map_err(|_| serde::de::Error::custom("Deserialization failed"))
117 }
118}
119
120#[serde_as]
121#[derive(Serialize, Deserialize)]
122#[serde(rename_all = "camelCase")]
123pub(crate) struct GasCostSummaryJson {
124 #[serde_as(as = "DisplayFromStr")]
125 computation_cost: u64,
126 #[serde_as(as = "DisplayFromStr")]
127 storage_cost: u64,
128 #[serde_as(as = "DisplayFromStr")]
129 storage_rebate: u64,
130 #[serde_as(as = "DisplayFromStr")]
131 non_refundable_storage_fee: u64,
132}
133
134impl From<GasCostSummaryJson> for GasCostSummary {
135 fn from(
136 GasCostSummaryJson {
137 computation_cost,
138 storage_cost,
139 storage_rebate,
140 non_refundable_storage_fee,
141 }: GasCostSummaryJson,
142 ) -> Self {
143 Self {
144 computation_cost,
145 storage_cost,
146 storage_rebate,
147 non_refundable_storage_fee,
148 }
149 }
150}
151
152impl From<GasCostSummary> for GasCostSummaryJson {
153 fn from(
154 GasCostSummary {
155 computation_cost,
156 storage_cost,
157 storage_rebate,
158 non_refundable_storage_fee,
159 }: GasCostSummary,
160 ) -> Self {
161 Self {
162 computation_cost,
163 storage_cost,
164 storage_rebate,
165 non_refundable_storage_fee,
166 }
167 }
168}
169
170#[cfg(test)]
171mod test {
172 use super::*;
173
174 #[serde_as]
175 #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
176 #[serde(rename_all = "camelCase")]
177 struct Bcs {
178 #[serde_as(as = "Base64orBase58")]
179 bcs: Vec<u8>,
180 }
181
182 #[test]
183 fn new_bcs_format() {
184 let bytes = vec![0, 1, 2, 3, 4];
185 let untagged_base58 = r#"{"bcs":"12VfUX"}"#;
186 let tagged_base58 = r#"{"bcsEncoding":"base58","bcs":"12VfUX"}"#;
187 let tagged_base64 = r#"{"bcsEncoding":"base64","bcs":"AAECAwQ="}"#;
188
189 println!(
190 "{}",
191 serde_json::to_string(&Bcs { bcs: bytes.clone() }).unwrap()
192 );
193
194 assert_eq!(
195 bytes,
196 serde_json::from_str::<Bcs>(untagged_base58).unwrap().bcs
197 );
198 assert_eq!(
199 bytes,
200 serde_json::from_str::<Bcs>(tagged_base58).unwrap().bcs
201 );
202 assert_eq!(
203 bytes,
204 serde_json::from_str::<Bcs>(tagged_base64).unwrap().bcs
205 );
206
207 let name = serde_json::from_str::<Bcs>(tagged_base64).unwrap();
209 let json = serde_json::to_string(&name).unwrap();
210 let from_json = serde_json::from_str::<Bcs>(&json).unwrap();
211 assert_eq!(name, from_json);
212
213 let name = serde_json::from_str::<Bcs>(tagged_base58).unwrap();
215 let json = serde_json::to_string(&name).unwrap();
216 let from_json = serde_json::from_str::<Bcs>(&json).unwrap();
217 assert_eq!(name, from_json);
218 }
219}