1use crate::{Error, Map, Value};
2
3mod iter_ser;
4mod map_key;
5mod maps;
6mod seq;
7mod tagged_bytes;
8mod text_repr;
9
10use maps::{SerializeMap, SerializeStructVariant, SerializeTupleVariant};
11use seq::{SerializeSeq, SerializeSeqNoBytes};
12use tagged_bytes::TaggedBytes;
13
14impl serde::Serialize for Value {
15 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
16 where
17 S: serde::Serializer,
18 {
19 use crate::TOKEN;
20
21 let (i, k) = self.kind().variant();
22 if s.is_human_readable() {
23 text_repr::TextRepr::new(self).serialize(s)
24 } else {
25 match self {
26 Value::Null => s.serialize_newtype_variant(TOKEN, i, k, &()),
27 Value::String(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
28 Value::Bool(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
29 Value::U64(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
30 Value::I64(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
31 Value::F64(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
32 Value::Decimal(v) => {
33 s.serialize_newtype_variant(TOKEN, i, k, &crate::Bytes(&v.serialize()))
34 }
35 Value::I128(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
36 Value::U128(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
37 Value::B32(v) => s.serialize_newtype_variant(TOKEN, i, k, &crate::Bytes(v)),
38 Value::B64(v) => s.serialize_newtype_variant(TOKEN, i, k, &crate::Bytes(v)),
39 Value::Bytes(v) => s.serialize_newtype_variant(TOKEN, i, k, &crate::Bytes(v)),
40 Value::Array(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
41 Value::Map(v) => s.serialize_newtype_variant(TOKEN, i, k, &v),
42 }
43 }
44 }
45}
46
47pub struct Serializer;
49
50impl serde::Serializer for Serializer {
51 type Ok = Value;
52 type Error = Error;
53
54 type SerializeSeq = SerializeSeqNoBytes;
55 type SerializeTuple = SerializeSeqNoBytes;
56 type SerializeTupleStruct = SerializeSeqNoBytes;
57 type SerializeTupleVariant = SerializeTupleVariant;
58 type SerializeMap = SerializeMap;
59 type SerializeStruct = SerializeMap;
60 type SerializeStructVariant = SerializeStructVariant;
61
62 fn is_human_readable(&self) -> bool {
63 false
64 }
65
66 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
67 Ok(Value::from(v))
68 }
69
70 fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
71 Ok(Value::from(v))
72 }
73
74 fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
75 Ok(Value::from(v))
76 }
77
78 fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
79 Ok(Value::from(v))
80 }
81
82 fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
83 Ok(Value::from(v))
84 }
85
86 fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
87 Ok(Value::from(v))
88 }
89
90 fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
91 Ok(Value::from(v))
92 }
93
94 fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
95 Ok(Value::from(v))
96 }
97
98 fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
99 Ok(Value::from(v))
100 }
101
102 fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
103 Ok(Value::from(v))
104 }
105
106 fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
107 Ok(Value::from(v))
108 }
109
110 fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
111 Ok(Value::from(v))
112 }
113
114 fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
115 Ok(Value::from(v))
116 }
117
118 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
119 Ok(Value::String(String::from(v)))
120 }
121
122 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
123 Ok(Value::from(v))
124 }
125
126 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
127 Ok(Value::from(v))
128 }
129
130 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
131 Ok(Value::Null)
132 }
133
134 fn serialize_some<T>(self, v: &T) -> Result<Self::Ok, Self::Error>
135 where
136 T: ?Sized + serde::Serialize,
137 {
138 v.serialize(self)
139 }
140
141 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
142 Ok(Value::Null)
143 }
144
145 fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
146 self.serialize_unit()
147 }
148
149 fn serialize_unit_variant(
150 self,
151 _: &'static str,
152 _: u32,
153 variant: &'static str,
154 ) -> Result<Self::Ok, Self::Error> {
155 self.serialize_str(variant)
156 }
157
158 fn serialize_newtype_struct<T>(self, name: &'static str, v: &T) -> Result<Self::Ok, Self::Error>
159 where
160 T: ?Sized + serde::Serialize,
161 {
162 match name {
163 crate::with::decimal::TOKEN => v.serialize(TaggedBytes::Decimal),
164 #[cfg(feature = "solana")]
165 crate::with::keypair::TOKEN
166 | crate::with::signature::TOKEN
167 | crate::with::pubkey::TOKEN => v.serialize(TaggedBytes::Bytes),
168 _ => v.serialize(self),
169 }
170 }
171
172 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
173 Ok(SerializeSeqNoBytes::default())
174 }
175
176 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
177 self.serialize_seq(Some(len))
178 }
179
180 fn serialize_tuple_struct(
181 self,
182 _: &'static str,
183 len: usize,
184 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
185 self.serialize_seq(Some(len))
186 }
187
188 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
189 Ok(SerializeMap {
190 map: Map::with_capacity(len.unwrap_or(0)),
191 next_key: None,
192 })
193 }
194
195 fn serialize_struct(
196 self,
197 _: &'static str,
198 len: usize,
199 ) -> Result<Self::SerializeStruct, Self::Error> {
200 Ok(SerializeMap {
201 map: Map::with_capacity(len),
202 next_key: None,
203 })
204 }
205
206 fn serialize_struct_variant(
207 self,
208 _: &'static str,
209 _: u32,
210 variant: &'static str,
211 len: usize,
212 ) -> Result<Self::SerializeStructVariant, Self::Error> {
213 Ok(SerializeStructVariant {
214 name: variant,
215 map: Map::with_capacity(len),
216 })
217 }
218
219 fn serialize_newtype_variant<T>(
220 self,
221 name: &'static str,
222 index: u32,
223 variant: &'static str,
224 value: &T,
225 ) -> Result<Self::Ok, Self::Error>
226 where
227 T: ?Sized + serde::Serialize,
228 {
229 if name == crate::TOKEN {
230 match index {
231 6 => value.serialize(TaggedBytes::Decimal),
233 9..=11 => value.serialize(TaggedBytes::Bytes),
235 12 => value.serialize(SerializeSeqNoBytes::default()),
237 _ => value.serialize(Serializer),
239 }
240 } else {
241 let value = value.serialize(Serializer)?;
242 Ok(Value::Map(Map::from([(variant.to_owned(), value)])))
243 }
244 }
245
246 fn serialize_tuple_variant(
247 self,
248 _: &'static str,
249 _: u32,
250 variant: &'static str,
251 _: usize,
252 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
253 Ok(SerializeTupleVariant {
254 name: variant,
255 seq: SerializeSeq::new(),
256 })
257 }
258}
259
260#[cfg(test)]
261mod tests {
262 use super::*;
263 use rust_decimal::Decimal;
264 use serde::Serialize;
265 use std::collections::HashMap;
266
267 #[test]
268 fn test_value_to_value() {
269 fn t(v: Value) {
270 assert_eq!(v.serialize(Serializer).unwrap(), v);
271 }
272 t(Value::Null);
273 t(Value::I64(0i64));
274 t(Value::String(String::new()));
275 t(Value::Bool(false));
276 t(Value::U64(0));
277 t(Value::I64(0));
278 t(Value::F64(0.0));
279 t(Value::Decimal(Decimal::MAX));
280 t(Value::I128(0));
281 t(Value::U128(0));
282 t(Value::B32([0u8; 32]));
283 t(Value::B64([0u8; 64]));
284 t(Value::Bytes(bytes::Bytes::from_static(
285 "something".as_bytes(),
286 )));
287 t(Value::Array(Vec::new()));
288 t(Value::Map(Map::new()));
289 }
290
291 fn s<T: Serialize>(t: T) -> Value {
292 t.serialize(Serializer).unwrap()
293 }
294
295 #[test]
296 fn test_serialize_primitive() {
297 assert_eq!(s(0u8), Value::U64(0));
298 assert_eq!(s(0u16), Value::U64(0));
299 assert_eq!(s(0u32), Value::U64(0));
300 assert_eq!(s(0u64), Value::U64(0));
301 assert_eq!(s(0i8), Value::I64(0));
302 assert_eq!(s(0i16), Value::I64(0));
303 assert_eq!(s(0i32), Value::I64(0));
304 assert_eq!(s(0i64), Value::I64(0));
305 assert_eq!(s(0f32), Value::F64(0.0));
306 assert_eq!(s(0f64), Value::F64(0.0));
307 assert_eq!(s(true), Value::Bool(true));
308 assert_eq!(s(Option::<()>::None), Value::Null);
309 assert_eq!(s(()), Value::Null);
310 assert_eq!(s("end"), Value::String("end".to_owned()));
311 assert_eq!(s([1i32]), Value::Array(vec![Value::I64(1)]));
312 assert_eq!(
313 s((1i32, -2i32, "hello")),
314 Value::Array(vec![
315 Value::I64(1),
316 Value::I64(-2),
317 Value::String("hello".to_owned())
318 ])
319 );
320 assert_eq!(s([0u8; 0]), Value::Array(Vec::new()));
321 assert_eq!(s([()]), Value::Array([Value::Null].to_vec()));
322 assert_eq!(
323 s(HashMap::from([("a".to_owned(), -1i32)])),
324 Value::Map(Map::from([("a".to_owned(), Value::I64(-1))]))
325 );
326 assert_eq!(s(crate::Bytes(&[2u8; 64])), Value::B64([2; 64]));
328 }
329
330 #[test]
331 fn test_derive() {
332 #[derive(Serialize)]
333 struct A {
334 a: Noop,
335 b: B,
336 c0: C,
337 c1: C,
338 #[serde(flatten)]
339 f: C,
340 #[serde(rename = "NULL")]
341 null: Option<i32>,
342 i: I32,
343 }
344
345 #[derive(Serialize)]
346 struct Noop;
347
348 #[derive(Serialize)]
349 struct B {}
350
351 #[derive(Serialize)]
352 struct I32(i32);
353
354 #[derive(Serialize)]
355 struct C {
356 #[serde(skip_serializing_if = "Option::is_none")]
357 y: Option<i32>,
358 }
359
360 assert_eq!(
361 s(A {
362 a: Noop,
363 b: B {},
364 c0: C { y: None },
365 c1: C { y: Some(1) },
366 f: C { y: Some(2) },
367 null: None,
368 i: I32(323232),
369 }),
370 Value::Map(
371 [
372 ("a".into(), Value::Null),
373 ("b".into(), Value::Map(Map::new())),
374 ("c0".into(), Value::Map(Map::new())),
375 (
376 "c1".into(),
377 Value::Map([("y".into(), Value::I64(1))].into())
378 ),
379 ("y".into(), Value::I64(2)),
380 ("NULL".into(), Value::Null),
381 ("i".into(), Value::I64(323232)),
382 ]
383 .into()
384 )
385 );
386 }
387
388 #[test]
389 fn test_enum() {
390 #[derive(Serialize, Debug, PartialEq)]
391 enum Enum0 {
392 V0,
393 V1,
394 #[serde(rename = "var")]
395 V2,
396 V3(i32),
397 }
398 assert_eq!(s(Enum0::V0), Value::String("V0".to_owned()));
399 assert_eq!(s(Enum0::V1), Value::String("V1".to_owned()));
400 assert_eq!(s(Enum0::V2), Value::String("var".to_owned()));
401 assert_eq!(
402 s(Enum0::V3(-1)),
403 Value::Map(Map::from([("V3".to_owned(), Value::I64(-1))]))
404 );
405 }
406}