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("network.id"), |_| Self::NetworkID),
31 map(pair(opt(terminated(ProgramID::parse, tag("/"))), tag("checksum")), |(program_id, _)| {
33 Self::Checksum(program_id)
34 }),
35 map(pair(opt(terminated(ProgramID::parse, tag("/"))), tag("edition")), |(program_id, _)| {
36 Self::Edition(program_id)
37 }),
38 map(pair(opt(terminated(ProgramID::parse, tag("/"))), tag("program_owner")), |(program_id, _)| {
40 Self::ProgramOwner(program_id)
41 }),
42 map(ProgramID::parse, |program_id| Self::ProgramID(program_id)),
45 map(Literal::parse, |literal| Self::Literal(literal)),
46 map(Register::parse, |register| Self::Register(register)),
47 ))(string)
48 }
49}
50
51impl<N: Network> FromStr for Operand<N> {
52 type Err = Error;
53
54 #[inline]
56 fn from_str(string: &str) -> Result<Self> {
57 match Self::parse(string) {
58 Ok((remainder, object)) => {
59 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
61 Ok(object)
63 }
64 Err(error) => bail!("Failed to parse string. {error}"),
65 }
66 }
67}
68
69impl<N: Network> Debug for Operand<N> {
70 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
72 Display::fmt(self, f)
73 }
74}
75
76impl<N: Network> Display for Operand<N> {
77 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
79 match self {
80 Self::Literal(literal) => Display::fmt(literal, f),
82 Self::Register(register) => Display::fmt(register, f),
84 Self::ProgramID(program_id) => Display::fmt(program_id, f),
86 Self::Signer => write!(f, "self.signer"),
88 Self::Caller => write!(f, "self.caller"),
90 Self::BlockHeight => write!(f, "block.height"),
92 Self::NetworkID => write!(f, "network.id"),
94 Self::Checksum(program_id) => match program_id {
96 Some(program_id) => write!(f, "{program_id}/checksum"),
97 None => write!(f, "checksum"),
98 },
99 Self::Edition(program_id) => match program_id {
101 Some(program_id) => write!(f, "{program_id}/edition"),
102 None => write!(f, "edition"),
103 },
104 Self::ProgramOwner(program_id) => match program_id {
106 Some(program_id) => write!(f, "{program_id}/program_owner"),
107 None => write!(f, "program_owner"),
108 },
109 }
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 use console::network::MainnetV0;
117
118 type CurrentNetwork = MainnetV0;
119
120 #[test]
121 fn test_operand_parse() -> Result<()> {
122 let operand = Operand::<CurrentNetwork>::parse("1field").unwrap().1;
123 assert_eq!(Operand::Literal(Literal::from_str("1field")?), operand);
124
125 let operand = Operand::<CurrentNetwork>::parse("r0").unwrap().1;
126 assert_eq!(Operand::Register(Register::from_str("r0")?), operand);
127
128 let operand = Operand::<CurrentNetwork>::parse("r0.owner").unwrap().1;
129 assert_eq!(Operand::Register(Register::from_str("r0.owner")?), operand);
130
131 let operand = Operand::<CurrentNetwork>::parse("howard.aleo").unwrap().1;
132 assert_eq!(Operand::ProgramID(ProgramID::from_str("howard.aleo")?), operand);
133
134 let operand = Operand::<CurrentNetwork>::parse("self.signer").unwrap().1;
135 assert_eq!(Operand::Signer, operand);
136
137 let operand = Operand::<CurrentNetwork>::parse("self.caller").unwrap().1;
138 assert_eq!(Operand::Caller, operand);
139
140 let operand = Operand::<CurrentNetwork>::parse("block.height").unwrap().1;
141 assert_eq!(Operand::BlockHeight, operand);
142
143 let operand = Operand::<CurrentNetwork>::parse("network.id").unwrap().1;
144 assert_eq!(Operand::NetworkID, operand);
145
146 let operand = Operand::<CurrentNetwork>::parse("group::GEN").unwrap().1;
147 assert_eq!(Operand::Literal(Literal::Group(Group::generator())), operand);
148
149 let operand = Operand::<CurrentNetwork>::parse("checksum").unwrap().1;
150 assert_eq!(Operand::Checksum(None), operand);
151
152 let operand = Operand::<CurrentNetwork>::parse("token.aleo/checksum").unwrap().1;
153 assert_eq!(Operand::Checksum(Some(ProgramID::from_str("token.aleo")?)), operand);
154
155 let operand = Operand::<CurrentNetwork>::parse("edition").unwrap().1;
156 assert_eq!(Operand::Edition(None), operand);
157
158 let operand = Operand::<CurrentNetwork>::parse("token.aleo/edition").unwrap().1;
159 assert_eq!(Operand::Edition(Some(ProgramID::from_str("token.aleo")?)), operand);
160
161 let operand = Operand::<CurrentNetwork>::parse("program_owner").unwrap().1;
162 assert_eq!(Operand::ProgramOwner(None), operand);
163
164 let operand = Operand::<CurrentNetwork>::parse("token.aleo/program_owner").unwrap().1;
165 assert_eq!(Operand::ProgramOwner(Some(ProgramID::from_str("token.aleo")?)), operand);
166
167 let (remainder, operand) = Operand::<CurrentNetwork>::parse("1field.private").unwrap();
169 assert_eq!(Operand::Literal(Literal::from_str("1field")?), operand);
170 assert_eq!(".private", remainder);
171
172 Ok(())
173 }
174
175 #[test]
176 fn test_operand_display() {
177 let operand = Operand::<CurrentNetwork>::parse("1field").unwrap().1;
178 assert_eq!(format!("{operand}"), "1field");
179
180 let operand = Operand::<CurrentNetwork>::parse("r0").unwrap().1;
181 assert_eq!(format!("{operand}"), "r0");
182
183 let operand = Operand::<CurrentNetwork>::parse("r0.owner").unwrap().1;
184 assert_eq!(format!("{operand}"), "r0.owner");
185
186 let operand = Operand::<CurrentNetwork>::parse("howard.aleo").unwrap().1;
187 assert_eq!(format!("{operand}"), "howard.aleo");
188
189 let operand = Operand::<CurrentNetwork>::parse("self.signer").unwrap().1;
190 assert_eq!(format!("{operand}"), "self.signer");
191
192 let operand = Operand::<CurrentNetwork>::parse("self.caller").unwrap().1;
193 assert_eq!(format!("{operand}"), "self.caller");
194
195 let operand = Operand::<CurrentNetwork>::parse("checksum").unwrap().1;
196 assert_eq!(format!("{operand}"), "checksum");
197
198 let operand = Operand::<CurrentNetwork>::parse("foo.aleo/checksum").unwrap().1;
199 assert_eq!(format!("{operand}"), "foo.aleo/checksum");
200
201 let operand = Operand::<CurrentNetwork>::parse("edition").unwrap().1;
202 assert_eq!(format!("{operand}"), "edition");
203
204 let operand = Operand::<CurrentNetwork>::parse("foo.aleo/edition").unwrap().1;
205 assert_eq!(format!("{operand}"), "foo.aleo/edition");
206
207 let operand = Operand::<CurrentNetwork>::parse("program_owner").unwrap().1;
208 assert_eq!(format!("{operand}"), "program_owner");
209
210 let operand = Operand::<CurrentNetwork>::parse("foo.aleo/program_owner").unwrap().1;
211 assert_eq!(format!("{operand}"), "foo.aleo/program_owner");
212
213 let operand = Operand::<CurrentNetwork>::parse("group::GEN").unwrap().1;
214 assert_eq!(
215 format!("{operand}"),
216 "1540945439182663264862696551825005342995406165131907382295858612069623286213group"
217 );
218 }
219
220 #[test]
221 fn test_operand_from_str_fails() -> Result<()> {
222 assert!(Operand::<CurrentNetwork>::from_str("1field.private").is_err());
223 Ok(())
224 }
225}