Skip to main content

platform_value/value_serialization/
ser.rs

1use crate::error::Error;
2use crate::value_map::ValueMap;
3use crate::{to_value, Value};
4use base64::prelude::BASE64_STANDARD;
5use base64::Engine;
6use serde::ser::Serialize;
7use std::fmt::Display;
8
9// We only use our own error type; no need for From conversions provided by the
10// standard library's try! macro. This reduces lines of LLVM IR by 4%.
11macro_rules! tri {
12    ($e:expr $(,)?) => {
13        match $e {
14            core::result::Result::Ok(val) => val,
15            core::result::Result::Err(err) => return core::result::Result::Err(err),
16        }
17    };
18}
19
20impl Serialize for Value {
21    #[inline]
22    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23    where
24        S: ::serde::Serializer,
25    {
26        match self {
27            Value::Null => serializer.serialize_unit(),
28            Value::Bool(b) => serializer.serialize_bool(*b),
29            Value::Array(v) => v.serialize(serializer),
30            Value::Map(m) => {
31                use serde::ser::SerializeMap;
32                let mut map = tri!(serializer.serialize_map(Some(m.len())));
33                for (k, v) in m {
34                    tri!(map.serialize_entry(k, v));
35                }
36                map.end()
37            }
38            Value::U128(i) => serializer.serialize_u128(*i),
39            Value::I128(i) => serializer.serialize_i128(*i),
40            Value::U64(i) => serializer.serialize_u64(*i),
41            Value::I64(i) => serializer.serialize_i64(*i),
42            Value::U32(i) => serializer.serialize_u32(*i),
43            Value::I32(i) => serializer.serialize_i32(*i),
44            Value::U16(i) => serializer.serialize_u16(*i),
45            Value::I16(i) => serializer.serialize_i16(*i),
46            Value::U8(i) => serializer.serialize_u8(*i),
47            Value::I8(i) => serializer.serialize_i8(*i),
48            Value::Bytes(bytes) => {
49                if serializer.is_human_readable() {
50                    serializer.serialize_str(BASE64_STANDARD.encode(bytes).as_str())
51                } else {
52                    serializer.serialize_bytes(bytes)
53                }
54            }
55            Value::Bytes20(bytes) => {
56                if serializer.is_human_readable() {
57                    serializer.serialize_str(BASE64_STANDARD.encode(bytes).as_str())
58                } else {
59                    serializer.serialize_bytes(bytes)
60                }
61            }
62            Value::Bytes32(bytes) => {
63                if serializer.is_human_readable() {
64                    serializer.serialize_str(BASE64_STANDARD.encode(bytes).as_str())
65                } else {
66                    serializer.serialize_bytes(bytes)
67                }
68            }
69            Value::Bytes36(bytes) => {
70                if serializer.is_human_readable() {
71                    serializer.serialize_str(BASE64_STANDARD.encode(bytes).as_str())
72                } else {
73                    serializer.serialize_bytes(bytes)
74                }
75            }
76            Value::Identifier(bytes) => {
77                if serializer.is_human_readable() {
78                    serializer.serialize_str(bs58::encode(bytes).into_string().as_str())
79                } else {
80                    serializer.serialize_bytes(bytes)
81                }
82            }
83            Value::Float(f64) => serializer.serialize_f64(*f64),
84            Value::Text(string) => serializer.serialize_str(string),
85            Value::EnumU8(_x) => todo!(),
86            Value::EnumString(_x) => todo!(),
87        }
88    }
89}
90
91/// Serializer whose output is a `Value`.
92///
93/// This is the serializer that backs [`platform_value::to_value`][crate::to_value].
94/// Unlike the main platform_value serializer which goes from some serializable
95/// value of type `T` to JSON text, this one goes from `T` to
96/// `platform_value::Value`.
97///
98/// The `to_value` function is implementable as:
99///
100/// ```
101/// use serde::Serialize;
102/// use serde_json::{Error, Value};
103///
104/// pub fn to_value<T>(input: T) -> Result<Value, Error>
105/// where
106///     T: Serialize,
107/// {
108///     input.serialize(serde_json::value::Serializer)
109/// }
110/// ```
111pub struct Serializer;
112
113impl serde::Serializer for Serializer {
114    type Ok = Value;
115    type Error = Error;
116
117    type SerializeSeq = SerializeVec;
118    type SerializeTuple = SerializeVec;
119    type SerializeTupleStruct = SerializeVec;
120    type SerializeTupleVariant = SerializeTupleVariant;
121    type SerializeMap = SerializeMap;
122    type SerializeStruct = SerializeMap;
123    type SerializeStructVariant = SerializeStructVariant;
124
125    #[inline]
126    fn serialize_bool(self, value: bool) -> Result<Value, Error> {
127        Ok(Value::Bool(value))
128    }
129
130    #[inline]
131    fn serialize_i8(self, value: i8) -> Result<Value, Error> {
132        Ok(Value::I8(value))
133    }
134
135    #[inline]
136    fn serialize_i16(self, value: i16) -> Result<Value, Error> {
137        Ok(Value::I16(value))
138    }
139
140    #[inline]
141    fn serialize_i32(self, value: i32) -> Result<Value, Error> {
142        Ok(Value::I32(value))
143    }
144
145    #[inline]
146    fn serialize_i64(self, value: i64) -> Result<Value, Error> {
147        Ok(Value::I64(value))
148    }
149
150    #[inline]
151    fn serialize_i128(self, value: i128) -> Result<Value, Error> {
152        Ok(Value::I128(value))
153    }
154
155    #[inline]
156    fn serialize_u8(self, value: u8) -> Result<Value, Error> {
157        Ok(Value::U8(value))
158    }
159
160    #[inline]
161    fn serialize_u16(self, value: u16) -> Result<Value, Error> {
162        Ok(Value::U16(value))
163    }
164
165    #[inline]
166    fn serialize_u32(self, value: u32) -> Result<Value, Error> {
167        Ok(Value::U32(value))
168    }
169
170    #[inline]
171    fn serialize_u64(self, value: u64) -> Result<Value, Error> {
172        Ok(Value::U64(value))
173    }
174
175    #[inline]
176    fn serialize_u128(self, value: u128) -> Result<Value, Error> {
177        Ok(Value::U128(value))
178    }
179
180    #[inline]
181    fn serialize_f32(self, value: f32) -> Result<Value, Error> {
182        self.serialize_f64(value as f64)
183    }
184
185    #[inline]
186    fn serialize_f64(self, value: f64) -> Result<Value, Error> {
187        Ok(Value::Float(value))
188    }
189
190    #[inline]
191    fn serialize_char(self, value: char) -> Result<Value, Error> {
192        let mut s = String::new();
193        s.push(value);
194        Ok(Value::Text(s))
195    }
196
197    #[inline]
198    fn serialize_str(self, value: &str) -> Result<Value, Error> {
199        Ok(Value::Text(value.to_owned()))
200    }
201
202    #[inline]
203    fn serialize_bytes(self, value: &[u8]) -> Result<Value, Error> {
204        Ok(match value.len() {
205            32 => Value::Bytes32(value.try_into().unwrap()),
206            36 => Value::Bytes36(value.try_into().unwrap()),
207            20 => Value::Bytes20(value.try_into().unwrap()),
208            _ => Value::Bytes(value.to_vec()),
209        })
210    }
211
212    #[inline]
213    fn serialize_unit(self) -> Result<Value, Error> {
214        Ok(Value::Null)
215    }
216
217    #[inline]
218    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
219        self.serialize_unit()
220    }
221
222    #[inline]
223    fn serialize_unit_variant(
224        self,
225        _name: &'static str,
226        _variant_index: u32,
227        variant: &'static str,
228    ) -> Result<Value, Error> {
229        self.serialize_str(variant)
230    }
231
232    #[inline]
233    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Value, Error>
234    where
235        T: ?Sized + Serialize,
236    {
237        match name {
238            "Identifier" => match value.serialize(self)? {
239                Value::Bytes32(b) => Ok(Value::Identifier(b)),
240                data => {
241                    panic!("expected Value::Bytes32, got: {data:#?}")
242                }
243            },
244            _ => value.serialize(self),
245        }
246    }
247
248    fn serialize_newtype_variant<T>(
249        self,
250        _name: &'static str,
251        _variant_index: u32,
252        variant: &'static str,
253        value: &T,
254    ) -> Result<Value, Error>
255    where
256        T: ?Sized + Serialize,
257    {
258        Ok(Value::Map(vec![(
259            Value::Text(String::from(variant)),
260            tri!(to_value(value)),
261        )]))
262    }
263
264    #[inline]
265    fn serialize_none(self) -> Result<Value, Error> {
266        self.serialize_unit()
267    }
268
269    #[inline]
270    fn serialize_some<T>(self, value: &T) -> Result<Value, Error>
271    where
272        T: ?Sized + Serialize,
273    {
274        value.serialize(self)
275    }
276
277    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
278        Ok(SerializeVec {
279            vec: Vec::with_capacity(len.unwrap_or(0)),
280        })
281    }
282
283    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Error> {
284        self.serialize_seq(Some(len))
285    }
286
287    fn serialize_tuple_struct(
288        self,
289        _name: &'static str,
290        len: usize,
291    ) -> Result<Self::SerializeTupleStruct, Error> {
292        self.serialize_seq(Some(len))
293    }
294
295    fn serialize_tuple_variant(
296        self,
297        _name: &'static str,
298        _variant_index: u32,
299        variant: &'static str,
300        len: usize,
301    ) -> Result<Self::SerializeTupleVariant, Error> {
302        Ok(SerializeTupleVariant {
303            name: String::from(variant),
304            vec: Vec::with_capacity(len),
305        })
306    }
307
308    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
309        Ok(SerializeMap::Map {
310            map: Vec::new(),
311            next_key: None,
312        })
313    }
314
315    fn serialize_struct(
316        self,
317        _name: &'static str,
318        len: usize,
319    ) -> Result<Self::SerializeStruct, Error> {
320        self.serialize_map(Some(len))
321    }
322
323    fn serialize_struct_variant(
324        self,
325        _name: &'static str,
326        _variant_index: u32,
327        variant: &'static str,
328        _len: usize,
329    ) -> Result<Self::SerializeStructVariant, Error> {
330        Ok(SerializeStructVariant {
331            name: String::from(variant),
332            map: Vec::new(),
333        })
334    }
335
336    fn collect_str<T>(self, value: &T) -> Result<Value, Error>
337    where
338        T: ?Sized + Display,
339    {
340        Ok(Value::Text(value.to_string()))
341    }
342
343    fn is_human_readable(&self) -> bool {
344        false
345    }
346}
347
348pub struct SerializeVec {
349    vec: Vec<Value>,
350}
351
352pub struct SerializeTupleVariant {
353    name: String,
354    vec: Vec<Value>,
355}
356
357pub enum SerializeMap {
358    Map {
359        map: ValueMap,
360        next_key: Option<Value>,
361    },
362}
363
364pub struct SerializeStructVariant {
365    name: String,
366    map: ValueMap,
367}
368
369impl serde::ser::SerializeSeq for SerializeVec {
370    type Ok = Value;
371    type Error = Error;
372
373    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
374    where
375        T: ?Sized + Serialize,
376    {
377        self.vec.push(tri!(to_value(value)));
378        Ok(())
379    }
380
381    fn end(self) -> Result<Value, Error> {
382        Ok(Value::Array(self.vec))
383    }
384}
385
386impl serde::ser::SerializeTuple for SerializeVec {
387    type Ok = Value;
388    type Error = Error;
389
390    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
391    where
392        T: ?Sized + Serialize,
393    {
394        serde::ser::SerializeSeq::serialize_element(self, value)
395    }
396
397    fn end(self) -> Result<Value, Error> {
398        serde::ser::SerializeSeq::end(self)
399    }
400}
401
402// impl serde::ser::SerializeTuple for SerializeSizedVec {
403//     type Ok = Value;
404//     type Error = Error;
405//
406//     fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
407//         where
408//             T: ?Sized + Serialize,
409//     {
410//         serde::ser::SerializeSeq::serialize_element(self, value)
411//     }
412//
413//     fn end(self) -> Result<Value, Error> {
414//         if self.size == 32 {
415//             Ok(Value::Bytes32(self.vec))
416//         } else {
417//             serde::ser::SerializeSeq::end(self)
418//         }
419//     }
420// }
421
422impl serde::ser::SerializeTupleStruct for SerializeVec {
423    type Ok = Value;
424    type Error = Error;
425
426    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
427    where
428        T: ?Sized + Serialize,
429    {
430        serde::ser::SerializeSeq::serialize_element(self, value)
431    }
432
433    fn end(self) -> Result<Value, Error> {
434        serde::ser::SerializeSeq::end(self)
435    }
436}
437
438impl serde::ser::SerializeTupleVariant for SerializeTupleVariant {
439    type Ok = Value;
440    type Error = Error;
441
442    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
443    where
444        T: ?Sized + Serialize,
445    {
446        self.vec.push(tri!(to_value(value)));
447        Ok(())
448    }
449
450    fn end(self) -> Result<Value, Error> {
451        Ok(Value::Map(vec![(
452            Value::Text(self.name),
453            Value::Array(self.vec),
454        )]))
455    }
456}
457
458impl serde::ser::SerializeMap for SerializeMap {
459    type Ok = Value;
460    type Error = Error;
461
462    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Error>
463    where
464        T: ?Sized + Serialize,
465    {
466        // Route keys through the regular Serializer (HR=false) so typed keys
467        // — e.g. `Value::Bytes32` for `BTreeMap<ProTxHash, _>` — survive the
468        // round-trip. The previous design routed keys through a dedicated
469        // string-only `MapKeySerializer` (HR=true), which forced hash-typed
470        // keys to be hex strings on serialize while the deserialize side
471        // (HR=false) expected bytes — non-round-trippable.
472        match self {
473            SerializeMap::Map { next_key, .. } => {
474                *next_key = Some(tri!(to_value(key)));
475                Ok(())
476            }
477        }
478    }
479
480    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Error>
481    where
482        T: ?Sized + Serialize,
483    {
484        match self {
485            SerializeMap::Map { map, next_key } => {
486                let key = next_key.take();
487                // Panic because this indicates a bug in the program rather than an
488                // expected failure.
489                let key = key.expect("serialize_value called before serialize_key");
490                map.push((key, tri!(to_value(value))));
491                Ok(())
492            }
493        }
494    }
495
496    fn end(self) -> Result<Value, Error> {
497        match self {
498            SerializeMap::Map { map, .. } => Ok(Value::Map(map)),
499        }
500    }
501}
502
503// `MapKeySerializer` was removed: keys now flow through the regular
504// `Serializer` so typed keys (e.g. `Value::Bytes32` for `BTreeMap<ProTxHash, _>`)
505// round-trip symmetrically with the deserialize side. The previous
506// string-only serializer artificially forced every key to `Value::Text`,
507// causing an HR-asymmetry with the deserialize path. The
508// `Error::KeyMustBeAString` variant is left in the error enum for SemVer
509// stability but is no longer produced by this crate.
510
511impl serde::ser::SerializeStruct for SerializeMap {
512    type Ok = Value;
513    type Error = Error;
514
515    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
516    where
517        T: ?Sized + Serialize,
518    {
519        match self {
520            SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value),
521        }
522    }
523
524    fn end(self) -> Result<Value, Error> {
525        match self {
526            SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self),
527        }
528    }
529}
530
531impl serde::ser::SerializeStructVariant for SerializeStructVariant {
532    type Ok = Value;
533    type Error = Error;
534
535    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
536    where
537        T: ?Sized + Serialize,
538    {
539        self.map
540            .push((Value::Text(String::from(key)), tri!(to_value(value))));
541        Ok(())
542    }
543
544    fn end(self) -> Result<Value, Error> {
545        Ok(Value::Map(vec![(
546            Value::Text(self.name),
547            Value::Map(self.map),
548        )]))
549    }
550}
551
552#[cfg(test)]
553#[allow(clippy::approx_constant)]
554mod tests {
555    use super::*;
556    use serde::{Deserialize, Serialize};
557
558    // ---------------------------------------------------------------
559    // Serialize primitives
560    // ---------------------------------------------------------------
561
562    #[test]
563    fn serialize_bool() {
564        assert_eq!(to_value(true).unwrap(), Value::Bool(true));
565        assert_eq!(to_value(false).unwrap(), Value::Bool(false));
566    }
567
568    #[test]
569    fn serialize_i8() {
570        assert_eq!(to_value(-42i8).unwrap(), Value::I8(-42));
571    }
572
573    #[test]
574    fn serialize_i16() {
575        assert_eq!(to_value(-1000i16).unwrap(), Value::I16(-1000));
576    }
577
578    #[test]
579    fn serialize_i32() {
580        assert_eq!(to_value(-100_000i32).unwrap(), Value::I32(-100_000));
581    }
582
583    #[test]
584    fn serialize_i64() {
585        assert_eq!(
586            to_value(-10_000_000_000i64).unwrap(),
587            Value::I64(-10_000_000_000)
588        );
589    }
590
591    #[test]
592    fn serialize_i128() {
593        assert_eq!(to_value(i128::MIN).unwrap(), Value::I128(i128::MIN));
594    }
595
596    #[test]
597    fn serialize_u8() {
598        assert_eq!(to_value(42u8).unwrap(), Value::U8(42));
599    }
600
601    #[test]
602    fn serialize_u16() {
603        assert_eq!(to_value(1000u16).unwrap(), Value::U16(1000));
604    }
605
606    #[test]
607    fn serialize_u32() {
608        assert_eq!(to_value(100_000u32).unwrap(), Value::U32(100_000));
609    }
610
611    #[test]
612    fn serialize_u64() {
613        assert_eq!(
614            to_value(10_000_000_000u64).unwrap(),
615            Value::U64(10_000_000_000)
616        );
617    }
618
619    #[test]
620    fn serialize_u128() {
621        assert_eq!(to_value(u128::MAX).unwrap(), Value::U128(u128::MAX));
622    }
623
624    #[test]
625    fn serialize_f32() {
626        let val = to_value(3.14f32).unwrap();
627        match val {
628            Value::Float(f) => assert!((f - 3.14f32 as f64).abs() < 1e-6),
629            _ => panic!("expected Float"),
630        }
631    }
632
633    #[test]
634    fn serialize_f64() {
635        assert_eq!(to_value(2.718f64).unwrap(), Value::Float(2.718));
636    }
637
638    #[test]
639    fn serialize_char() {
640        let val = to_value('A').unwrap();
641        assert_eq!(val, Value::Text("A".to_string()));
642    }
643
644    #[test]
645    fn serialize_str() {
646        assert_eq!(to_value("hello").unwrap(), Value::Text("hello".to_string()));
647    }
648
649    #[test]
650    fn serialize_string() {
651        assert_eq!(
652            to_value("world".to_string()).unwrap(),
653            Value::Text("world".to_string())
654        );
655    }
656
657    // ---------------------------------------------------------------
658    // Serialize unit / None / Some
659    // ---------------------------------------------------------------
660
661    #[test]
662    fn serialize_unit() {
663        assert_eq!(to_value(()).unwrap(), Value::Null);
664    }
665
666    #[test]
667    fn serialize_none() {
668        let val: Option<u32> = None;
669        assert_eq!(to_value(val).unwrap(), Value::Null);
670    }
671
672    #[test]
673    fn serialize_some() {
674        let val: Option<u32> = Some(42);
675        assert_eq!(to_value(val).unwrap(), Value::U32(42));
676    }
677
678    // ---------------------------------------------------------------
679    // Serialize sequences and tuples
680    // ---------------------------------------------------------------
681
682    #[test]
683    fn serialize_vec() {
684        let val = to_value(vec![1u32, 2, 3]).unwrap();
685        assert_eq!(
686            val,
687            Value::Array(vec![Value::U32(1), Value::U32(2), Value::U32(3)])
688        );
689    }
690
691    #[test]
692    fn serialize_empty_vec() {
693        let val = to_value(Vec::<u32>::new()).unwrap();
694        assert_eq!(val, Value::Array(vec![]));
695    }
696
697    #[test]
698    fn serialize_tuple() {
699        let val = to_value((1u32, "hello")).unwrap();
700        assert_eq!(
701            val,
702            Value::Array(vec![Value::U32(1), Value::Text("hello".into())])
703        );
704    }
705
706    // ---------------------------------------------------------------
707    // Serialize maps
708    // ---------------------------------------------------------------
709
710    #[test]
711    fn serialize_hashmap() {
712        let mut map = std::collections::HashMap::new();
713        map.insert("key", 42u32);
714        let val = to_value(map).unwrap();
715        match val {
716            Value::Map(entries) => {
717                assert_eq!(entries.len(), 1);
718                assert_eq!(entries[0].0, Value::Text("key".into()));
719                assert_eq!(entries[0].1, Value::U32(42));
720            }
721            _ => panic!("expected Map"),
722        }
723    }
724
725    // ---------------------------------------------------------------
726    // Serialize structs
727    // ---------------------------------------------------------------
728
729    #[test]
730    fn serialize_struct() {
731        #[derive(Serialize)]
732        struct Point {
733            x: i32,
734            y: i32,
735        }
736        let val = to_value(Point { x: 10, y: 20 }).unwrap();
737        match val {
738            Value::Map(entries) => {
739                assert_eq!(entries.len(), 2);
740                assert_eq!(entries[0].0, Value::Text("x".into()));
741                assert_eq!(entries[0].1, Value::I32(10));
742                assert_eq!(entries[1].0, Value::Text("y".into()));
743                assert_eq!(entries[1].1, Value::I32(20));
744            }
745            _ => panic!("expected Map"),
746        }
747    }
748
749    #[test]
750    fn serialize_unit_struct() {
751        #[derive(Serialize)]
752        struct Empty;
753        assert_eq!(to_value(Empty).unwrap(), Value::Null);
754    }
755
756    #[test]
757    fn serialize_newtype_struct() {
758        #[derive(Serialize)]
759        struct Wrapper(u32);
760        assert_eq!(to_value(Wrapper(42)).unwrap(), Value::U32(42));
761    }
762
763    #[test]
764    fn serialize_tuple_struct() {
765        #[derive(Serialize)]
766        struct Pair(u32, String);
767        let val = to_value(Pair(1, "two".into())).unwrap();
768        assert_eq!(
769            val,
770            Value::Array(vec![Value::U32(1), Value::Text("two".into())])
771        );
772    }
773
774    // ---------------------------------------------------------------
775    // Serialize enums
776    // ---------------------------------------------------------------
777
778    #[test]
779    fn serialize_unit_variant() {
780        #[derive(Serialize)]
781        enum Color {
782            Red,
783        }
784        assert_eq!(
785            to_value(Color::Red).unwrap(),
786            Value::Text("Red".to_string())
787        );
788    }
789
790    #[test]
791    fn serialize_newtype_variant() {
792        #[derive(Serialize)]
793        enum Wrapper {
794            Count(u32),
795        }
796        let val = to_value(Wrapper::Count(42)).unwrap();
797        assert_eq!(
798            val,
799            Value::Map(vec![(Value::Text("Count".into()), Value::U32(42))])
800        );
801    }
802
803    #[test]
804    fn serialize_tuple_variant() {
805        #[derive(Serialize)]
806        enum Pair {
807            Coords(i32, i32),
808        }
809        let val = to_value(Pair::Coords(10, 20)).unwrap();
810        assert_eq!(
811            val,
812            Value::Map(vec![(
813                Value::Text("Coords".into()),
814                Value::Array(vec![Value::I32(10), Value::I32(20)])
815            )])
816        );
817    }
818
819    #[test]
820    fn serialize_struct_variant() {
821        #[derive(Serialize)]
822        enum Shape {
823            Circle { radius: u32 },
824        }
825        let val = to_value(Shape::Circle { radius: 5 }).unwrap();
826        assert_eq!(
827            val,
828            Value::Map(vec![(
829                Value::Text("Circle".into()),
830                Value::Map(vec![(Value::Text("radius".into()), Value::U32(5))])
831            )])
832        );
833    }
834
835    // ---------------------------------------------------------------
836    // Serialize bytes (non-human-readable mode)
837    // ---------------------------------------------------------------
838
839    #[test]
840    fn serialize_bytes_32_becomes_bytes32() {
841        // Exactly 32 bytes should become Bytes32
842        let data = [1u8; 32];
843        use serde::Serializer;
844        let val = Serializer.serialize_bytes(&data).unwrap();
845        assert_eq!(val, Value::Bytes32(data));
846    }
847
848    #[test]
849    fn serialize_bytes_20_becomes_bytes20() {
850        let data = [2u8; 20];
851        use serde::Serializer;
852        let val = Serializer.serialize_bytes(&data).unwrap();
853        assert_eq!(val, Value::Bytes20(data));
854    }
855
856    #[test]
857    fn serialize_bytes_36_becomes_bytes36() {
858        let data = [3u8; 36];
859        use serde::Serializer;
860        let val = Serializer.serialize_bytes(&data).unwrap();
861        assert_eq!(val, Value::Bytes36(data));
862    }
863
864    #[test]
865    fn serialize_bytes_other_len_becomes_bytes() {
866        let data = vec![4u8; 10];
867        use serde::Serializer;
868        let val = Serializer.serialize_bytes(&data).unwrap();
869        assert_eq!(val, Value::Bytes(data));
870    }
871
872    // ---------------------------------------------------------------
873    // Serialize Value (the Serialize impl for Value)
874    // ---------------------------------------------------------------
875
876    #[test]
877    fn serialize_value_null() {
878        let val = Value::Null;
879        let serialized = to_value(&val).unwrap();
880        assert_eq!(serialized, Value::Null);
881    }
882
883    #[test]
884    fn serialize_value_bool() {
885        let val = Value::Bool(true);
886        let serialized = to_value(&val).unwrap();
887        assert_eq!(serialized, Value::Bool(true));
888    }
889
890    #[test]
891    fn serialize_value_integer_types() {
892        let cases = vec![
893            Value::U8(1),
894            Value::I8(-1),
895            Value::U16(100),
896            Value::I16(-100),
897            Value::U32(1000),
898            Value::I32(-1000),
899            Value::U64(10000),
900            Value::I64(-10000),
901            Value::U128(100000),
902            Value::I128(-100000),
903        ];
904        for val in cases {
905            let serialized = to_value(&val).unwrap();
906            assert_eq!(serialized, val);
907        }
908    }
909
910    #[test]
911    fn serialize_value_float() {
912        let val = Value::Float(3.14);
913        let serialized = to_value(&val).unwrap();
914        assert_eq!(serialized, Value::Float(3.14));
915    }
916
917    #[test]
918    fn serialize_value_text() {
919        let val = Value::Text("hello".into());
920        let serialized = to_value(&val).unwrap();
921        assert_eq!(serialized, Value::Text("hello".into()));
922    }
923
924    #[test]
925    fn serialize_value_array() {
926        let val = Value::Array(vec![Value::U8(1), Value::U8(2)]);
927        let serialized = to_value(&val).unwrap();
928        assert_eq!(serialized, val);
929    }
930
931    #[test]
932    fn serialize_value_map() {
933        let val = Value::Map(vec![(Value::Text("k".into()), Value::U32(42))]);
934        let serialized = to_value(&val).unwrap();
935        assert_eq!(serialized, val);
936    }
937
938    #[test]
939    fn serialize_value_bytes() {
940        let val = Value::Bytes(vec![1, 2, 3, 4, 5]);
941        let serialized = to_value(&val).unwrap();
942        // Non-human-readable serializer: serialized as bytes
943        assert_eq!(serialized, val);
944    }
945
946    #[test]
947    fn serialize_value_bytes20() {
948        let val = Value::Bytes20([1u8; 20]);
949        let serialized = to_value(&val).unwrap();
950        // serialize_bytes with len=20 -> Bytes20
951        assert_eq!(serialized, val);
952    }
953
954    #[test]
955    fn serialize_value_bytes32() {
956        let val = Value::Bytes32([2u8; 32]);
957        let serialized = to_value(&val).unwrap();
958        assert_eq!(serialized, val);
959    }
960
961    #[test]
962    fn serialize_value_bytes36() {
963        let val = Value::Bytes36([3u8; 36]);
964        let serialized = to_value(&val).unwrap();
965        assert_eq!(serialized, val);
966    }
967
968    #[test]
969    fn serialize_value_identifier() {
970        let val = Value::Identifier([4u8; 32]);
971        let serialized = to_value(&val).unwrap();
972        // Non-human-readable: identifier serialized as bytes (32 bytes -> Bytes32)
973        assert_eq!(serialized, Value::Bytes32([4u8; 32]));
974    }
975
976    // ---------------------------------------------------------------
977    // Map key types — platform_value allows any Value variant as a key.
978    // This is unlike serde_json (which mandates string keys for JSON
979    // compatibility); platform_value's richer Value type means a
980    // `BTreeMap<ProTxHash, _>` round-trips with `Value::Bytes32` keys.
981    // ---------------------------------------------------------------
982
983    #[test]
984    fn map_key_bool_now_supported() {
985        let mut map = std::collections::HashMap::new();
986        map.insert(true, "value");
987        let result = to_value(map).expect("bool keys are now allowed");
988        match result {
989            Value::Map(entries) => {
990                assert_eq!(entries.len(), 1);
991                assert_eq!(entries[0].0, Value::Bool(true));
992            }
993            _ => panic!("expected Map"),
994        }
995    }
996
997    #[test]
998    fn map_key_string_works() {
999        let mut map = std::collections::HashMap::new();
1000        map.insert("key".to_string(), 42u32);
1001        let result = to_value(map);
1002        assert!(result.is_ok());
1003    }
1004
1005    #[test]
1006    fn map_key_integer_works() {
1007        let mut map = std::collections::HashMap::new();
1008        map.insert(42u32, "value");
1009        let result = to_value(map);
1010        assert!(result.is_ok());
1011    }
1012
1013    #[test]
1014    fn map_key_bytes_round_trips_as_bytes32() {
1015        // The motivating use case: BTreeMap<ProTxHash, _> in dashpay/platform.
1016        // Hash types serialize via `serialize_bytes` (HR=false). With typed
1017        // map keys, the result must be `Value::Bytes32`, not a stringified
1018        // hex form — symmetric with the deserialize side which expects bytes.
1019        use serde::{ser::SerializeMap as _, Serializer};
1020
1021        // Drive serialize_bytes directly — the cheapest way to exercise
1022        // the path without pulling in a full Hash type.
1023        let mut s = Serializer.serialize_map(Some(1)).unwrap();
1024        struct BytesKey([u8; 32]);
1025        impl serde::Serialize for BytesKey {
1026            fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1027                s.serialize_bytes(&self.0)
1028            }
1029        }
1030        s.serialize_entry(&BytesKey([0xab; 32]), &7u32).unwrap();
1031        let val = serde::ser::SerializeMap::end(s).unwrap();
1032        match val {
1033            Value::Map(entries) => {
1034                assert_eq!(entries.len(), 1);
1035                assert_eq!(entries[0].0, Value::Bytes32([0xab; 32]));
1036                assert_eq!(entries[0].1, Value::U32(7));
1037            }
1038            _ => panic!("expected Value::Map"),
1039        }
1040    }
1041
1042    // ---------------------------------------------------------------
1043    // Round-trip tests: Rust -> Value -> Rust
1044    // ---------------------------------------------------------------
1045
1046    #[test]
1047    fn round_trip_complex_struct() {
1048        #[derive(Debug, PartialEq, Serialize, Deserialize)]
1049        struct Complex {
1050            name: String,
1051            count: u64,
1052            active: bool,
1053            score: f64,
1054            tags: Vec<String>,
1055            metadata: Option<String>,
1056        }
1057
1058        let original = Complex {
1059            name: "test".into(),
1060            count: 42,
1061            active: true,
1062            score: 3.14,
1063            tags: vec!["a".into(), "b".into()],
1064            metadata: Some("info".into()),
1065        };
1066        let val = to_value(&original).unwrap();
1067        let recovered: Complex = crate::from_value(val).unwrap();
1068        assert_eq!(original, recovered);
1069    }
1070
1071    #[test]
1072    fn round_trip_nested() {
1073        #[derive(Debug, PartialEq, Serialize, Deserialize)]
1074        struct Inner {
1075            x: i32,
1076        }
1077        #[derive(Debug, PartialEq, Serialize, Deserialize)]
1078        struct Outer {
1079            inner: Inner,
1080        }
1081
1082        let original = Outer {
1083            inner: Inner { x: -5 },
1084        };
1085        let val = to_value(&original).unwrap();
1086        let recovered: Outer = crate::from_value(val).unwrap();
1087        assert_eq!(original, recovered);
1088    }
1089
1090    #[test]
1091    fn collect_str_produces_text() {
1092        use serde::Serializer;
1093        let val = Serializer.collect_str(&42).unwrap();
1094        assert_eq!(val, Value::Text("42".to_string()));
1095    }
1096}