/ ledger / block / src / transactions / rejected / serialize.rs
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 Rejected<N> {
 19      /// Serializes the rejected transaction 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 => match self {
 23                  Self::Deployment(program_owner, deployment) => {
 24                      let mut object = serializer.serialize_struct("Rejected", 3)?;
 25                      object.serialize_field("type", "deployment")?;
 26                      object.serialize_field("program_owner", program_owner)?;
 27                      object.serialize_field("deployment", deployment)?;
 28                      object.end()
 29                  }
 30                  Self::Execution(execution) => {
 31                      let mut object = serializer.serialize_struct("Rejected", 2)?;
 32                      object.serialize_field("type", "execution")?;
 33                      object.serialize_field("execution", execution)?;
 34                      object.end()
 35                  }
 36              },
 37              false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
 38          }
 39      }
 40  }
 41  
 42  impl<'de, N: Network> Deserialize<'de> for Rejected<N> {
 43      /// Deserializes the confirmed transaction from a string or bytes.
 44      fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
 45          match deserializer.is_human_readable() {
 46              true => {
 47                  // Parse the rejected transaction from a string into a value.
 48                  let mut object = serde_json::Value::deserialize(deserializer)?;
 49  
 50                  // Parse the type.
 51                  let type_ = object.get("type").and_then(|t| t.as_str());
 52  
 53                  // Recover the rejected transaction.
 54                  match type_ {
 55                      Some("deployment") => {
 56                          // Parse the program owner.
 57                          let program_owner: ProgramOwner<N> =
 58                              DeserializeExt::take_from_value::<D>(&mut object, "program_owner")?;
 59                          // Parse the deployment.
 60                          let deployment: Deployment<N> =
 61                              DeserializeExt::take_from_value::<D>(&mut object, "deployment")?;
 62                          // Return the rejected deployment.
 63                          Ok(Self::new_deployment(program_owner, deployment))
 64                      }
 65                      Some("execution") => {
 66                          // Parse the execution.
 67                          let execution: Execution<N> = DeserializeExt::take_from_value::<D>(&mut object, "execution")?;
 68                          // Return the rejected execution.
 69                          Ok(Self::new_execution(execution))
 70                      }
 71                      _ => Err(de::Error::custom("Invalid rejected transaction type")),
 72                  }
 73              }
 74              false => {
 75                  FromBytesDeserializer::<Self>::deserialize_with_size_encoding(deserializer, "confirmed transaction")
 76              }
 77          }
 78      }
 79  }
 80  
 81  #[cfg(test)]
 82  mod tests {
 83      use super::*;
 84  
 85      fn check_serde_json<
 86          T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
 87      >(
 88          expected: T,
 89      ) {
 90          // Serialize
 91          let expected_string = expected.to_string();
 92          let candidate_string = serde_json::to_string(&expected).unwrap();
 93          let candidate = serde_json::from_str::<T>(&candidate_string).unwrap();
 94          assert_eq!(expected, candidate);
 95          assert_eq!(expected_string, candidate_string);
 96          assert_eq!(expected_string, candidate.to_string());
 97  
 98          // Deserialize
 99          assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}")));
100          assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
101      }
102  
103      fn check_bincode<
104          T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
105      >(
106          expected: T,
107      ) {
108          // Serialize
109          let expected_bytes = expected.to_bytes_le().unwrap();
110          let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap();
111          assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);
112  
113          // Deserialize
114          assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap());
115          assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap());
116      }
117  
118      #[test]
119      fn test_serde_json() {
120          for rejected in crate::transactions::rejected::test_helpers::sample_rejected_transactions() {
121              check_serde_json(rejected);
122          }
123      }
124  
125      #[test]
126      fn test_bincode() {
127          for rejected in crate::transactions::rejected::test_helpers::sample_rejected_transactions() {
128              check_bincode(rejected);
129          }
130      }
131  }