snarkvm_ledger_block/transactions/rejected_reason/
serialize.rs1use super::*;
17
18impl<N: Network> Serialize for RejectedReason<N> {
19 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
21 match serializer.is_human_readable() {
22 true => match self {
23 Self::DuplicateProgramID(program_id) => {
24 let mut object = serializer.serialize_struct("RejectedReason", 2)?;
25 object.serialize_field("type", "duplicate_program_id")?;
26 object.serialize_field("program_id", program_id)?;
27 object.end()
28 }
29 Self::Finalize { program_id, edition, resource, index, command } => {
30 let mut object = serializer.serialize_struct("RejectedReason", 6)?;
31 object.serialize_field("type", "finalize")?;
32 object.serialize_field("program_id", program_id)?;
33 object.serialize_field("edition", edition)?;
34 object.serialize_field("resource", resource)?;
35 object.serialize_field("index", index)?;
36 object.serialize_field("command", &command.to_string())?;
38 object.end()
39 }
40 Self::VM(program_id, resource) => {
41 let mut object = serializer.serialize_struct(
43 "RejectedReason",
44 1 + program_id.is_some() as usize * 2 + resource.is_some() as usize,
45 )?;
46 object.serialize_field("type", "non_finalize")?;
47 if let Some((pid, edition)) = program_id {
48 object.serialize_field("program_id", pid)?;
49 object.serialize_field("edition", edition)?;
50 }
51 if let Some(resource) = resource {
52 object.serialize_field("resource", resource)?;
53 }
54 object.end()
55 }
56 },
57 false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
58 }
59 }
60}
61
62impl<'de, N: Network> Deserialize<'de> for RejectedReason<N> {
63 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
65 match deserializer.is_human_readable() {
66 true => {
67 let mut object = serde_json::Value::deserialize(deserializer)?;
69 let type_ = object.get("type").and_then(|t| t.as_str());
71 match type_ {
73 Some("duplicate_program_id") => {
74 let program_id: ProgramID<N> = DeserializeExt::take_from_value::<D>(&mut object, "program_id")?;
75 Ok(Self::DuplicateProgramID(program_id))
76 }
77 Some("finalize") => {
78 let program_id: ProgramID<N> = DeserializeExt::take_from_value::<D>(&mut object, "program_id")?;
79 let edition: u16 = DeserializeExt::take_from_value::<D>(&mut object, "edition")?;
80 let resource: Identifier<N> = DeserializeExt::take_from_value::<D>(&mut object, "resource")?;
81 let index: usize = DeserializeExt::take_from_value::<D>(&mut object, "index")?;
82 let command_str: String = DeserializeExt::take_from_value::<D>(&mut object, "command")?;
84 let command = command_str.parse::<Command<N>>().map_err(de::Error::custom)?;
85 Ok(Self::Finalize { program_id, edition, resource, index, command: Box::new(command) })
86 }
87 Some("non_finalize") => {
88 let program_id = match object.get("program_id").and_then(|v| v.as_str()) {
90 Some(s) => {
91 let pid = ProgramID::<N>::from_str(s).map_err(de::Error::custom)?;
92 let edition: u16 = DeserializeExt::take_from_value::<D>(&mut object, "edition")?;
93 Some((pid, edition))
94 }
95 None => None,
96 };
97 let resource = match object.get("resource").and_then(|v| v.as_str()) {
98 Some(s) => Some(Identifier::<N>::from_str(s).map_err(de::Error::custom)?),
99 None => None,
100 };
101 Ok(Self::VM(program_id, resource))
102 }
103 _ => Err(de::Error::custom("Invalid rejected reason type")),
104 }
105 }
106 false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "rejected reason"),
107 }
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 type CurrentNetwork = console::network::MainnetV0;
116
117 fn check_serde_json(expected: RejectedReason<CurrentNetwork>) {
118 let expected_string = expected.to_string();
120 let candidate_string = serde_json::to_string(&expected).unwrap();
121 let candidate = serde_json::from_str::<RejectedReason<CurrentNetwork>>(&candidate_string).unwrap();
122 assert_eq!(expected, candidate);
123 assert_eq!(expected_string, candidate_string);
124 assert_eq!(expected_string, candidate.to_string());
125
126 assert_eq!(expected, RejectedReason::from_str(&expected_string).unwrap());
128 assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
129 }
130
131 fn check_bincode(expected: RejectedReason<CurrentNetwork>) {
132 let expected_bytes = expected.to_bytes_le().unwrap();
134 let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap();
135 assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
136
137 assert_eq!(expected, RejectedReason::read_le(&expected_bytes[..]).unwrap());
139 assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap());
140 }
141
142 #[test]
143 fn test_serde_json() {
144 for reason in test_helpers::sample_rejected_reasons::<CurrentNetwork>() {
145 check_serde_json(reason);
146 }
147 }
148
149 #[test]
150 fn test_bincode() {
151 for reason in test_helpers::sample_rejected_reasons::<CurrentNetwork>() {
152 check_bincode(reason);
153 }
154 }
155}