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