Skip to main content

snarkvm_console_program/data_types/value_type/
serialize.rs

1// Copyright (c) 2019-2026 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17
18impl<N: Network> Serialize for ValueType<N> {
19    /// Serializes the value type into string or bytes.
20    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
21        match serializer.is_human_readable() {
22            true => serializer.collect_str(self),
23            false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
24        }
25    }
26}
27
28impl<'de, N: Network> Deserialize<'de> for ValueType<N> {
29    /// Deserializes the value type from a string or bytes.
30    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
31        match deserializer.is_human_readable() {
32            true => FromStr::from_str(&String::deserialize(deserializer)?).map_err(de::Error::custom),
33            false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "value type"),
34        }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use snarkvm_console_network::MainnetV0;
42
43    type CurrentNetwork = MainnetV0;
44
45    /// Add test cases here to be checked for serialization.
46    const TEST_CASES: &[&str] = &[
47        // Literal
48        "address",
49        "boolean",
50        "field",
51        "group",
52        "i8",
53        "i16",
54        "i32",
55        "i64",
56        "i128",
57        "u8",
58        "u16",
59        "u32",
60        "u64",
61        "u128",
62        "scalar",
63        "string",
64        // Struct
65        "signature",
66        "message",
67        "item",
68        "passport",
69        "object",
70        "array",
71        // Future
72        "future",
73    ];
74
75    fn check_serde_json<
76        T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
77    >(
78        expected: T,
79    ) {
80        // Serialize
81        let expected_string = &expected.to_string();
82        let candidate_string = serde_json::to_string(&expected).unwrap();
83        assert_eq!(expected_string, serde_json::Value::from_str(&candidate_string).unwrap().as_str().unwrap());
84
85        // Deserialize
86        assert_eq!(expected, T::from_str(expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}")));
87        assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
88    }
89
90    fn check_bincode<
91        T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
92    >(
93        expected: T,
94    ) {
95        // Serialize
96        let expected_bytes = expected.to_bytes_le().unwrap();
97        let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap();
98        assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
99
100        // Deserialize
101        assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap());
102        assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap());
103    }
104
105    #[test]
106    fn test_serde_json() {
107        for case in TEST_CASES.iter() {
108            for mode in &["constant", "public", "private"] {
109                check_serde_json(ValueType::<CurrentNetwork>::from_str(&format!("{case}.{mode}")).unwrap());
110            }
111        }
112        check_serde_json(ValueType::<CurrentNetwork>::from_str("token.record").unwrap());
113        check_serde_json(ValueType::<CurrentNetwork>::from_str("hello_world.record").unwrap());
114        check_serde_json(ValueType::<CurrentNetwork>::from_str("hello_world.aleo/new.record").unwrap());
115        check_serde_json(ValueType::<CurrentNetwork>::from_str("dynamic.record").unwrap());
116        check_serde_json(ValueType::<CurrentNetwork>::from_str("dynamic.future").unwrap());
117    }
118
119    #[test]
120    fn test_bincode() {
121        for case in TEST_CASES.iter() {
122            for mode in &["constant", "public", "private"] {
123                check_bincode(ValueType::<CurrentNetwork>::from_str(&format!("{case}.{mode}")).unwrap());
124            }
125        }
126        check_bincode(ValueType::<CurrentNetwork>::from_str("token.record").unwrap());
127        check_bincode(ValueType::<CurrentNetwork>::from_str("hello_world.record").unwrap());
128        check_bincode(ValueType::<CurrentNetwork>::from_str("hello_world.aleo/new.record").unwrap());
129        check_bincode(ValueType::<CurrentNetwork>::from_str("dynamic.record").unwrap());
130        check_bincode(ValueType::<CurrentNetwork>::from_str("dynamic.future").unwrap());
131    }
132}