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 use alphavm_utilities::DeserializeExt; 19 20 impl<N: Network> Serialize for InputID<N> { 21 /// Serializes the input ID into string or bytes. 22 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 23 match serializer.is_human_readable() { 24 true => match self { 25 Self::Constant(id) => { 26 let mut input = serializer.serialize_struct("InputID", 2)?; 27 input.serialize_field("type", "constant")?; 28 input.serialize_field("id", &id)?; 29 input.end() 30 } 31 Self::Public(id) => { 32 let mut input = serializer.serialize_struct("InputID", 2)?; 33 input.serialize_field("type", "public")?; 34 input.serialize_field("id", &id)?; 35 input.end() 36 } 37 Self::Private(id) => { 38 let mut input = serializer.serialize_struct("InputID", 2)?; 39 input.serialize_field("type", "private")?; 40 input.serialize_field("id", &id)?; 41 input.end() 42 } 43 Self::Record(commitment, gamma, record_view_key, serial_number, tag) => { 44 let mut input = serializer.serialize_struct("InputID", 5)?; 45 input.serialize_field("type", "record")?; 46 input.serialize_field("commitment", &commitment)?; 47 input.serialize_field("gamma", &gamma)?; 48 input.serialize_field("record_view_key", &record_view_key)?; 49 input.serialize_field("serial_number", &serial_number)?; 50 input.serialize_field("tag", &tag)?; 51 input.end() 52 } 53 Self::ExternalRecord(id) => { 54 let mut input = serializer.serialize_struct("InputID", 2)?; 55 input.serialize_field("type", "external_record")?; 56 input.serialize_field("id", &id)?; 57 input.end() 58 } 59 }, 60 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer), 61 } 62 } 63 } 64 65 impl<'de, N: Network> Deserialize<'de> for InputID<N> { 66 /// Deserializes the input ID from a string or bytes. 67 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { 68 match deserializer.is_human_readable() { 69 true => { 70 // Parse the input ID from a string into a value. 71 let mut input = serde_json::Value::deserialize(deserializer)?; 72 // Recover the input. 73 let input_id = match input.get("type").and_then(|t| t.as_str()) { 74 Some("constant") => InputID::Constant(DeserializeExt::take_from_value::<D>(&mut input, "id")?), 75 Some("public") => InputID::Public(DeserializeExt::take_from_value::<D>(&mut input, "id")?), 76 Some("private") => InputID::Private(DeserializeExt::take_from_value::<D>(&mut input, "id")?), 77 Some("record") => InputID::Record( 78 DeserializeExt::take_from_value::<D>(&mut input, "commitment")?, 79 DeserializeExt::take_from_value::<D>(&mut input, "gamma")?, 80 DeserializeExt::take_from_value::<D>(&mut input, "record_view_key")?, 81 DeserializeExt::take_from_value::<D>(&mut input, "serial_number")?, 82 DeserializeExt::take_from_value::<D>(&mut input, "tag")?, 83 ), 84 Some("external_record") => { 85 InputID::ExternalRecord(DeserializeExt::take_from_value::<D>(&mut input, "id")?) 86 } 87 _ => return Err(de::Error::custom("Invalid input type")), 88 }; 89 Ok(input_id) 90 } 91 false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "input ID"), 92 } 93 } 94 } 95 96 #[cfg(test)] 97 mod tests { 98 use super::*; 99 use alphavm_console_network::MainnetV0; 100 101 type CurrentNetwork = MainnetV0; 102 103 /// Add test cases here to be checked for serialization. 104 const TEST_CASES: &[&str] = &[ 105 "{\"type\":\"constant\",\"id\":\"5field\"}", 106 "{\"type\":\"public\",\"id\":\"0field\"}", 107 "{\"type\":\"private\",\"id\":\"123field\"}", 108 "{\"type\":\"record\",\"commitment\":\"123123field\",\"tag\":\"0field\",\"record_view_key\":\"0field\",\"serial_number\":\"123456789field\",\"gamma\":\"0group\"}", 109 "{\"type\":\"external_record\",\"id\":\"123456789field\"}", 110 ]; 111 112 fn check_serde_json< 113 T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, 114 >( 115 expected: T, 116 ) { 117 // Serialize 118 let expected_string = expected.to_string(); 119 let candidate_string = serde_json::to_string(&expected).unwrap(); 120 let candidate = serde_json::from_str::<T>(&candidate_string).unwrap(); 121 assert_eq!(expected, candidate); 122 assert_eq!(expected_string, candidate_string); 123 assert_eq!(expected_string, candidate.to_string()); 124 125 // Deserialize 126 assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}"))); 127 assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap()); 128 } 129 130 fn check_bincode< 131 T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes, 132 >( 133 expected: T, 134 ) { 135 // Serialize 136 let expected_bytes = expected.to_bytes_le().unwrap(); 137 let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap(); 138 assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]); 139 140 // Deserialize 141 assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap()); 142 assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap()); 143 } 144 145 #[test] 146 fn test_serde_json() { 147 for case in TEST_CASES.iter() { 148 check_serde_json(InputID::<CurrentNetwork>::from_str(case).unwrap()); 149 } 150 } 151 152 #[test] 153 fn test_bincode() { 154 for case in TEST_CASES.iter() { 155 check_bincode(InputID::<CurrentNetwork>::from_str(case).unwrap()); 156 } 157 } 158 }