snarkvm_synthesizer_program/logic/instruction/operand/
parse.rs1use super::*;
17
18impl<N: Network> Parser for Operand<N> {
19 #[inline]
21 fn parse(string: &str) -> ParserResult<Self> {
22 alt((
24 map(tag("group::GEN"), |_| Self::Literal(Literal::Group(Group::generator()))),
27 map(tag("self.signer"), |_| Self::Signer),
28 map(tag("self.caller"), |_| Self::Caller),
29 map(tag("block.height"), |_| Self::BlockHeight),
30 map(tag("block.timestamp"), |_| Self::BlockTimestamp),
31 map(tag("network.id"), |_| Self::NetworkID),
32 map(
33 pair(tag("aleo::GENERATOR_POWERS"), opt(delimited(tag("["), U32::<N>::parse, tag("]")))),
34 |(_, index)| Self::AleoGeneratorPowers(index),
35 ),
36 map(tag("aleo::GENERATOR"), |_| Self::AleoGenerator),
37 map(pair(opt(terminated(ProgramID::parse, tag("/"))), tag("checksum")), |(program_id, _)| {
39 Self::Checksum(program_id)
40 }),
41 map(pair(opt(terminated(ProgramID::parse, tag("/"))), tag("edition")), |(program_id, _)| {
42 Self::Edition(program_id)
43 }),
44 map(pair(opt(terminated(ProgramID::parse, tag("/"))), tag("program_owner")), |(program_id, _)| {
46 Self::ProgramOwner(program_id)
47 }),
48 map(ProgramID::parse, |program_id| Self::ProgramID(program_id)),
51 map(Literal::parse, |literal| Self::Literal(literal)),
52 map(Register::parse, |register| Self::Register(register)),
53 ))(string)
54 }
55}
56
57impl<N: Network> FromStr for Operand<N> {
58 type Err = Error;
59
60 #[inline]
62 fn from_str(string: &str) -> Result<Self> {
63 match Self::parse(string) {
64 Ok((remainder, object)) => {
65 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
67 Ok(object)
69 }
70 Err(error) => bail!("Failed to parse string. {error}"),
71 }
72 }
73}
74
75impl<N: Network> Debug for Operand<N> {
76 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
78 Display::fmt(self, f)
79 }
80}
81
82impl<N: Network> Display for Operand<N> {
83 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
85 match self {
86 Self::Literal(literal) => Display::fmt(literal, f),
88 Self::Register(register) => Display::fmt(register, f),
90 Self::ProgramID(program_id) => Display::fmt(program_id, f),
92 Self::Signer => write!(f, "self.signer"),
94 Self::Caller => write!(f, "self.caller"),
96 Self::BlockHeight => write!(f, "block.height"),
98 Self::BlockTimestamp => write!(f, "block.timestamp"),
100 Self::NetworkID => write!(f, "network.id"),
102 Self::AleoGenerator => write!(f, "aleo::GENERATOR"),
104 Self::AleoGeneratorPowers(index) => match index {
106 None => write!(f, "aleo::GENERATOR_POWERS"),
107 Some(index) => write!(f, "aleo::GENERATOR_POWERS[{index}]"),
108 },
109 Self::Checksum(program_id) => match program_id {
111 Some(program_id) => write!(f, "{program_id}/checksum"),
112 None => write!(f, "checksum"),
113 },
114 Self::Edition(program_id) => match program_id {
116 Some(program_id) => write!(f, "{program_id}/edition"),
117 None => write!(f, "edition"),
118 },
119 Self::ProgramOwner(program_id) => match program_id {
121 Some(program_id) => write!(f, "{program_id}/program_owner"),
122 None => write!(f, "program_owner"),
123 },
124 }
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131 use console::network::MainnetV0;
132
133 type CurrentNetwork = MainnetV0;
134
135 #[test]
136 fn test_operand_parse() -> Result<()> {
137 let operand = Operand::<CurrentNetwork>::parse("1field").unwrap().1;
138 assert_eq!(Operand::Literal(Literal::from_str("1field")?), operand);
139
140 let operand = Operand::<CurrentNetwork>::parse("r0").unwrap().1;
141 assert_eq!(Operand::Register(Register::from_str("r0")?), operand);
142
143 let operand = Operand::<CurrentNetwork>::parse("r0.owner").unwrap().1;
144 assert_eq!(Operand::Register(Register::from_str("r0.owner")?), operand);
145
146 let operand = Operand::<CurrentNetwork>::parse("howard.aleo").unwrap().1;
147 assert_eq!(Operand::ProgramID(ProgramID::from_str("howard.aleo")?), operand);
148
149 let operand = Operand::<CurrentNetwork>::parse("self.signer").unwrap().1;
150 assert_eq!(Operand::Signer, operand);
151
152 let operand = Operand::<CurrentNetwork>::parse("self.caller").unwrap().1;
153 assert_eq!(Operand::Caller, operand);
154
155 let operand = Operand::<CurrentNetwork>::parse("block.height").unwrap().1;
156 assert_eq!(Operand::BlockHeight, operand);
157
158 let operand = Operand::<CurrentNetwork>::parse("block.timestamp").unwrap().1;
159 assert_eq!(Operand::BlockTimestamp, operand);
160
161 let operand = Operand::<CurrentNetwork>::parse("network.id").unwrap().1;
162 assert_eq!(Operand::NetworkID, operand);
163
164 let operand = Operand::<CurrentNetwork>::parse("aleo::GENERATOR").unwrap().1;
165 assert_eq!(Operand::AleoGenerator, operand);
166
167 let operand = Operand::<CurrentNetwork>::parse("aleo::GENERATOR_POWERS").unwrap().1;
168 assert_eq!(Operand::AleoGeneratorPowers(None), operand);
169
170 let operand = Operand::<CurrentNetwork>::parse("aleo::GENERATOR_POWERS[5u32]").unwrap().1;
171 assert_eq!(Operand::AleoGeneratorPowers(Some(U32::new(5u32))), operand);
172
173 let operand = Operand::<CurrentNetwork>::parse("group::GEN").unwrap().1;
174 assert_eq!(Operand::Literal(Literal::Group(Group::generator())), operand);
175
176 let operand = Operand::<CurrentNetwork>::parse("checksum").unwrap().1;
177 assert_eq!(Operand::Checksum(None), operand);
178
179 let operand = Operand::<CurrentNetwork>::parse("token.aleo/checksum").unwrap().1;
180 assert_eq!(Operand::Checksum(Some(ProgramID::from_str("token.aleo")?)), operand);
181
182 let operand = Operand::<CurrentNetwork>::parse("edition").unwrap().1;
183 assert_eq!(Operand::Edition(None), operand);
184
185 let operand = Operand::<CurrentNetwork>::parse("token.aleo/edition").unwrap().1;
186 assert_eq!(Operand::Edition(Some(ProgramID::from_str("token.aleo")?)), operand);
187
188 let operand = Operand::<CurrentNetwork>::parse("program_owner").unwrap().1;
189 assert_eq!(Operand::ProgramOwner(None), operand);
190
191 let operand = Operand::<CurrentNetwork>::parse("token.aleo/program_owner").unwrap().1;
192 assert_eq!(Operand::ProgramOwner(Some(ProgramID::from_str("token.aleo")?)), operand);
193
194 let (remainder, operand) = Operand::<CurrentNetwork>::parse("1field.private").unwrap();
196 assert_eq!(Operand::Literal(Literal::from_str("1field")?), operand);
197 assert_eq!(".private", remainder);
198
199 Ok(())
200 }
201
202 #[test]
203 fn test_operand_display() {
204 let operand = Operand::<CurrentNetwork>::parse("1field").unwrap().1;
205 assert_eq!(format!("{operand}"), "1field");
206
207 let operand = Operand::<CurrentNetwork>::parse("r0").unwrap().1;
208 assert_eq!(format!("{operand}"), "r0");
209
210 let operand = Operand::<CurrentNetwork>::parse("r0.owner").unwrap().1;
211 assert_eq!(format!("{operand}"), "r0.owner");
212
213 let operand = Operand::<CurrentNetwork>::parse("howard.aleo").unwrap().1;
214 assert_eq!(format!("{operand}"), "howard.aleo");
215
216 let operand = Operand::<CurrentNetwork>::parse("self.signer").unwrap().1;
217 assert_eq!(format!("{operand}"), "self.signer");
218
219 let operand = Operand::<CurrentNetwork>::parse("self.caller").unwrap().1;
220 assert_eq!(format!("{operand}"), "self.caller");
221
222 let operand = Operand::<CurrentNetwork>::parse("checksum").unwrap().1;
223 assert_eq!(format!("{operand}"), "checksum");
224
225 let operand = Operand::<CurrentNetwork>::parse("aleo::GENERATOR").unwrap().1;
226 assert_eq!(format!("{operand}"), "aleo::GENERATOR");
227
228 let operand = Operand::<CurrentNetwork>::parse("aleo::GENERATOR_POWERS").unwrap().1;
229 assert_eq!(format!("{operand}"), "aleo::GENERATOR_POWERS");
230
231 let operand = Operand::<CurrentNetwork>::parse("aleo::GENERATOR_POWERS[5u32]").unwrap().1;
232 assert_eq!(format!("{operand}"), "aleo::GENERATOR_POWERS[5u32]");
233
234 let operand = Operand::<CurrentNetwork>::parse("foo.aleo/checksum").unwrap().1;
235 assert_eq!(format!("{operand}"), "foo.aleo/checksum");
236
237 let operand = Operand::<CurrentNetwork>::parse("edition").unwrap().1;
238 assert_eq!(format!("{operand}"), "edition");
239
240 let operand = Operand::<CurrentNetwork>::parse("foo.aleo/edition").unwrap().1;
241 assert_eq!(format!("{operand}"), "foo.aleo/edition");
242
243 let operand = Operand::<CurrentNetwork>::parse("program_owner").unwrap().1;
244 assert_eq!(format!("{operand}"), "program_owner");
245
246 let operand = Operand::<CurrentNetwork>::parse("foo.aleo/program_owner").unwrap().1;
247 assert_eq!(format!("{operand}"), "foo.aleo/program_owner");
248
249 let operand = Operand::<CurrentNetwork>::parse("group::GEN").unwrap().1;
250 assert_eq!(
251 format!("{operand}"),
252 "1540945439182663264862696551825005342995406165131907382295858612069623286213group"
253 );
254 }
255
256 #[test]
257 fn test_operand_from_str_fails() -> Result<()> {
258 assert!(Operand::<CurrentNetwork>::from_str("1field.private").is_err());
259 Ok(())
260 }
261}