snarkvm_synthesizer_program/
bytes.rs1use super::*;
17
18impl<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>> FromBytes
19 for ProgramCore<N, Instruction, Command>
20{
21 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
22 let version = u8::read_le(&mut reader)?;
24 if version != 1 {
26 return Err(error("Invalid program version"));
27 }
28
29 let id = ProgramID::read_le(&mut reader)?;
31
32 let mut program = ProgramCore::new(id).map_err(|e| error(e.to_string()))?;
34
35 let imports_len = u8::read_le(&mut reader)?;
37 for _ in 0..imports_len {
39 program.add_import(Import::read_le(&mut reader)?).map_err(|e| error(e.to_string()))?;
40 }
41
42 let components_len = u16::read_le(&mut reader)?;
44 for _ in 0..components_len {
45 let variant = u8::read_le(&mut reader)?;
47 match variant {
49 0 => program.add_mapping(Mapping::read_le(&mut reader)?).map_err(|e| error(e.to_string()))?,
51 1 => program.add_struct(StructType::read_le(&mut reader)?).map_err(|e| error(e.to_string()))?,
53 2 => program.add_record(RecordType::read_le(&mut reader)?).map_err(|e| error(e.to_string()))?,
55 3 => program.add_closure(ClosureCore::read_le(&mut reader)?).map_err(|e| error(e.to_string()))?,
57 4 => program.add_function(FunctionCore::read_le(&mut reader)?).map_err(|e| error(e.to_string()))?,
59 _ => return Err(error(format!("Failed to parse program. Invalid component variant '{variant}'"))),
61 }
62 }
63
64 Ok(program)
65 }
66}
67
68impl<N: Network, Instruction: InstructionTrait<N>, Command: CommandTrait<N>> ToBytes
69 for ProgramCore<N, Instruction, Command>
70{
71 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
72 1u8.write_le(&mut writer)?;
74
75 self.id.write_le(&mut writer)?;
77
78 u8::try_from(self.imports.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?;
80 for import in self.imports.values() {
82 import.write_le(&mut writer)?;
83 }
84
85 u16::try_from(self.components.len()).map_err(|e| error(e.to_string()))?.write_le(&mut writer)?;
87 for (identifier, definition) in self.components.iter() {
89 match definition {
90 ProgramDefinition::Mapping => match self.mappings.get(identifier) {
91 Some(mapping) => {
92 0u8.write_le(&mut writer)?;
94 mapping.write_le(&mut writer)?;
96 }
97 None => return Err(error(format!("Mapping '{identifier}' is not defined"))),
98 },
99 ProgramDefinition::Struct => match self.structs.get(identifier) {
100 Some(struct_) => {
101 1u8.write_le(&mut writer)?;
103 struct_.write_le(&mut writer)?;
105 }
106 None => return Err(error(format!("Struct '{identifier}' is not defined."))),
107 },
108 ProgramDefinition::Record => match self.records.get(identifier) {
109 Some(record) => {
110 2u8.write_le(&mut writer)?;
112 record.write_le(&mut writer)?;
114 }
115 None => return Err(error(format!("Record '{identifier}' is not defined."))),
116 },
117 ProgramDefinition::Closure => match self.closures.get(identifier) {
118 Some(closure) => {
119 3u8.write_le(&mut writer)?;
121 closure.write_le(&mut writer)?;
123 }
124 None => return Err(error(format!("Closure '{identifier}' is not defined."))),
125 },
126 ProgramDefinition::Function => match self.functions.get(identifier) {
127 Some(function) => {
128 4u8.write_le(&mut writer)?;
130 function.write_le(&mut writer)?;
132 }
133 None => return Err(error(format!("Function '{identifier}' is not defined."))),
134 },
135 }
136 }
137
138 Ok(())
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145 use crate::Program;
146 use console::network::MainnetV0;
147
148 type CurrentNetwork = MainnetV0;
149
150 #[test]
151 fn test_bytes() -> Result<()> {
152 let program = r"
153program token.aleo;
154
155record token:
156 owner as address.private;
157 token_amount as u64.private;
158
159function compute:
160 input r0 as token.record;
161 add r0.token_amount r0.token_amount into r1;
162 output r1 as u64.private;";
163
164 let (string, expected) = Program::<CurrentNetwork>::parse(program).unwrap();
166 assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
167
168 let expected_bytes = expected.to_bytes_le()?;
169
170 let candidate = Program::<CurrentNetwork>::from_bytes_le(&expected_bytes)?;
171 assert_eq!(expected, candidate);
172 assert_eq!(expected_bytes, candidate.to_bytes_le()?);
173
174 Ok(())
175 }
176}