bytes.rs
 1  // Copyright (c) 2025-2026 ACDC Network
 2  // This file is part of the alphavm library.
 3  //
 4  // Alpha Chain | Delta Chain Protocol
 5  // International Monetary Graphite.
 6  //
 7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
 8  // They built world-class ZK infrastructure. We installed the EASY button.
 9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
11  //
12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
14  // No rights reserved. No permission required. No warranty. No refunds.
15  //
16  // https://creativecommons.org/publicdomain/zero/1.0/
17  // SPDX-License-Identifier: CC0-1.0
18  
19  use super::*;
20  
21  impl<N: Network> FromBytes for StructType<N> {
22      /// Reads a struct type from a buffer.
23      fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
24          // Read the name of the struct type.
25          let name = Identifier::read_le(&mut reader)?;
26  
27          // Read the number of members.
28          let num_members = u16::read_le(&mut reader)?;
29          // Ensure the number of members is within the maximum limit.
30          if num_members as usize > N::MAX_STRUCT_ENTRIES {
31              return Err(error(format!(
32                  "StructType exceeds size: expected <= {}, found {num_members}",
33                  N::MAX_STRUCT_ENTRIES
34              )));
35          }
36          // Read the members.
37          let mut members = IndexMap::with_capacity(num_members as usize);
38          for _ in 0..num_members {
39              // Read the identifier.
40              let identifier = Identifier::read_le(&mut reader)?;
41              // Read the plaintext type.
42              let plaintext_type = PlaintextType::read_le(&mut reader)?;
43              // Insert the member, and ensure the member has no duplicate names.
44              if members.insert(identifier, plaintext_type).is_some() {
45                  return Err(error(format!("Duplicate identifier in struct '{name}'")));
46              };
47          }
48  
49          Ok(Self { name, members })
50      }
51  }
52  
53  impl<N: Network> ToBytes for StructType<N> {
54      /// Writes the struct type to a buffer.
55      fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
56          // Ensure the number of members is within the maximum limit.
57          if self.members.len() > N::MAX_STRUCT_ENTRIES {
58              return Err(error("Failed to serialize struct: too many members"));
59          }
60  
61          // Write the name of the struct.
62          self.name.write_le(&mut writer)?;
63  
64          // Write the number of members.
65          u16::try_from(self.members.len()).or_halt_with::<N>("Struct length exceeds u16").write_le(&mut writer)?;
66          // Write the members as bytes.
67          for (identifier, plaintext_type) in &self.members {
68              // Write the identifier.
69              identifier.write_le(&mut writer)?;
70              // Write the plaintext type to the buffer.
71              plaintext_type.write_le(&mut writer)?;
72          }
73          Ok(())
74      }
75  }
76  
77  #[cfg(test)]
78  mod tests {
79      use super::*;
80      use alphavm_console_network::MainnetV0;
81  
82      type CurrentNetwork = MainnetV0;
83  
84      #[test]
85      fn test_bytes() -> Result<()> {
86          let expected =
87              StructType::<CurrentNetwork>::from_str("struct message:\n    first as field;\n    second as field;")?;
88          let candidate = StructType::from_bytes_le(&expected.to_bytes_le().unwrap()).unwrap();
89          assert_eq!(expected, candidate);
90          Ok(())
91      }
92  }