serialize.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm 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 16 use super::*; 17 18 impl<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 28 impl<'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)] 39 mod tests { 40 use super::*; 41 use alphavm_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.alpha/new.record").unwrap()); 115 } 116 117 #[test] 118 fn test_bincode() { 119 for case in TEST_CASES.iter() { 120 for mode in &["constant", "public", "private"] { 121 check_bincode(ValueType::<CurrentNetwork>::from_str(&format!("{case}.{mode}")).unwrap()); 122 } 123 } 124 check_bincode(ValueType::<CurrentNetwork>::from_str("token.record").unwrap()); 125 check_bincode(ValueType::<CurrentNetwork>::from_str("hello_world.record").unwrap()); 126 check_bincode(ValueType::<CurrentNetwork>::from_str("hello_world.alpha/new.record").unwrap()); 127 } 128 }