snarkvm_console_program/data/dynamic/future/
parse.rs1use super::*;
17
18impl<N: Network> Parser for DynamicFuture<N> {
19 #[inline]
25 fn parse(string: &str) -> ParserResult<Self> {
26 if let Ok(result) = Self::parse_human_readable(string) {
28 return Ok(result);
29 }
30 Self::parse_raw_fields(string)
32 }
33}
34
35impl<N: Network> DynamicFuture<N> {
36 fn parse_human_readable(string: &str) -> ParserResult<Self> {
38 let (string, _) = Sanitizer::parse(string)?;
40 let (string, _) = tag("{")(string)?;
42
43 let (string, _) = Sanitizer::parse(string)?;
45 let (string, _) = tag("_program_id")(string)?;
47 let (string, _) = Sanitizer::parse_whitespaces(string)?;
49 let (string, _) = tag(":")(string)?;
51 let (string, _) = Sanitizer::parse_whitespaces(string)?;
53 let (string, program_id) = ProgramID::parse(string)?;
55 let (string, _) = Sanitizer::parse_whitespaces(string)?;
57 let (string, _) = tag(",")(string)?;
59
60 let (string, _) = Sanitizer::parse(string)?;
62 let (string, _) = tag("_function_name")(string)?;
64 let (string, _) = Sanitizer::parse_whitespaces(string)?;
66 let (string, _) = tag(":")(string)?;
68 let (string, _) = Sanitizer::parse_whitespaces(string)?;
70 let (string, function_name) = Identifier::parse(string)?;
72 let (string, _) = Sanitizer::parse_whitespaces(string)?;
74 let (string, _) = tag(",")(string)?;
76
77 let (string, _) = Sanitizer::parse(string)?;
79 let (string, _) = tag("_checksum")(string)?;
81 let (string, _) = Sanitizer::parse_whitespaces(string)?;
83 let (string, _) = tag(":")(string)?;
85 let (string, _) = Sanitizer::parse_whitespaces(string)?;
87 let (string, checksum) = Field::parse(string)?;
89
90 let (string, _) = Sanitizer::parse(string)?;
92 let (string, _) = tag("}")(string)?;
94
95 let program_name = program_id.name().to_field().expect("identifier always fits in a field element");
98 let program_network = program_id.network().to_field().expect("identifier always fits in a field element");
99 let function_name_field = function_name.to_field().expect("identifier always fits in a field element");
100
101 Ok((string, Self::new_unchecked(program_name, program_network, function_name_field, checksum, None)))
102 }
103
104 fn parse_raw_fields(string: &str) -> ParserResult<Self> {
106 let (string, _) = Sanitizer::parse(string)?;
108 let (string, _) = tag("{")(string)?;
110
111 let (string, _) = Sanitizer::parse(string)?;
113 let (string, _) = tag("_program_name")(string)?;
115 let (string, _) = Sanitizer::parse_whitespaces(string)?;
117 let (string, _) = tag(":")(string)?;
119 let (string, _) = Sanitizer::parse_whitespaces(string)?;
121 let (string, program_name) = Field::parse(string)?;
123 let (string, _) = Sanitizer::parse_whitespaces(string)?;
125 let (string, _) = tag(",")(string)?;
127
128 let (string, _) = Sanitizer::parse(string)?;
130 let (string, _) = tag("_program_network")(string)?;
132 let (string, _) = Sanitizer::parse_whitespaces(string)?;
134 let (string, _) = tag(":")(string)?;
136 let (string, _) = Sanitizer::parse_whitespaces(string)?;
138 let (string, program_network) = Field::parse(string)?;
140 let (string, _) = Sanitizer::parse_whitespaces(string)?;
142 let (string, _) = tag(",")(string)?;
144
145 let (string, _) = Sanitizer::parse(string)?;
147 let (string, _) = tag("_function_name")(string)?;
149 let (string, _) = Sanitizer::parse_whitespaces(string)?;
151 let (string, _) = tag(":")(string)?;
153 let (string, _) = Sanitizer::parse_whitespaces(string)?;
155 let (string, function_name) = Field::parse(string)?;
157 let (string, _) = Sanitizer::parse_whitespaces(string)?;
159 let (string, _) = tag(",")(string)?;
161
162 let (string, _) = Sanitizer::parse(string)?;
164 let (string, _) = tag("_checksum")(string)?;
166 let (string, _) = Sanitizer::parse_whitespaces(string)?;
168 let (string, _) = tag(":")(string)?;
170 let (string, _) = Sanitizer::parse_whitespaces(string)?;
172 let (string, checksum) = Field::parse(string)?;
174
175 let (string, _) = Sanitizer::parse(string)?;
177 let (string, _) = tag("}")(string)?;
179
180 Ok((string, Self::new_unchecked(program_name, program_network, function_name, checksum, None)))
181 }
182}
183
184impl<N: Network> FromStr for DynamicFuture<N> {
185 type Err = Error;
186
187 fn from_str(string: &str) -> Result<Self> {
189 match Self::parse(string) {
190 Ok((remainder, object)) => {
191 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
193 Ok(object)
195 }
196 Err(error) => bail!("Failed to parse string. {error}"),
197 }
198 }
199}
200
201impl<N: Network> Debug for DynamicFuture<N> {
202 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
204 Display::fmt(self, f)
205 }
206}
207
208impl<N: Network> Display for DynamicFuture<N> {
209 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
214 let program_name_id = Identifier::<N>::from_field(&self.program_name);
216 let program_network_id = Identifier::<N>::from_field(&self.program_network);
217 let function_name_id = Identifier::<N>::from_field(&self.function_name);
218
219 if let (Ok(name), Ok(network), Ok(function)) = (program_name_id, program_network_id, function_name_id) {
221 if let Ok(program_id) = ProgramID::try_from((name, network)) {
222 return write!(
223 f,
224 "{{ _program_id: {program_id}, _function_name: {function}, _checksum: {} }}",
225 self.checksum()
226 );
227 }
228 }
229
230 write!(
232 f,
233 "{{ _program_name: {}, _program_network: {}, _function_name: {}, _checksum: {} }}",
234 self.program_name(),
235 self.program_network(),
236 self.function_name(),
237 self.checksum(),
238 )
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245 use crate::{Argument, Future, Plaintext};
246 use snarkvm_console_network::MainnetV0;
247
248 use core::str::FromStr;
249
250 type CurrentNetwork = MainnetV0;
251
252 #[test]
253 fn test_parse_display_roundtrip() {
254 let future = Future::<CurrentNetwork>::new(
256 crate::ProgramID::from_str("test.aleo").unwrap(),
257 crate::Identifier::from_str("foo").unwrap(),
258 vec![Argument::Plaintext(Plaintext::from_str("100u64").unwrap())],
259 );
260
261 let expected = DynamicFuture::from_future(&future).unwrap();
263
264 let expected_string = expected.to_string();
266
267 let candidate = DynamicFuture::<CurrentNetwork>::from_str(&expected_string).unwrap();
269
270 assert_eq!(expected.program_name(), candidate.program_name());
272 assert_eq!(expected.program_network(), candidate.program_network());
273 assert_eq!(expected.function_name(), candidate.function_name());
274 assert_eq!(expected.checksum(), candidate.checksum());
275 }
276
277 #[test]
278 fn test_parse_human_readable() {
279 let string = "{ _program_id: test.aleo, _function_name: foo, _checksum: 0field }";
281 let (remainder, candidate) = DynamicFuture::<CurrentNetwork>::parse(string).unwrap();
282 assert!(remainder.is_empty());
283
284 let program_name = Identifier::<CurrentNetwork>::from_field(candidate.program_name()).unwrap();
286 let program_network = Identifier::<CurrentNetwork>::from_field(candidate.program_network()).unwrap();
287 let function_name = Identifier::<CurrentNetwork>::from_field(candidate.function_name()).unwrap();
288
289 assert_eq!(program_name.to_string(), "test");
290 assert_eq!(program_network.to_string(), "aleo");
291 assert_eq!(function_name.to_string(), "foo");
292 assert_eq!(*candidate.checksum(), Field::from_u64(0));
293 }
294
295 #[test]
296 fn test_parse_raw_fields() {
297 let string = "{ _program_name: 0field, _program_network: 0field, _function_name: 0field, _checksum: 0field }";
299 let (remainder, candidate) = DynamicFuture::<CurrentNetwork>::parse(string).unwrap();
300 assert!(remainder.is_empty());
301 assert_eq!(*candidate.program_name(), Field::from_u64(0));
302 assert_eq!(*candidate.program_network(), Field::from_u64(0));
303 assert_eq!(*candidate.function_name(), Field::from_u64(0));
304 assert_eq!(*candidate.checksum(), Field::from_u64(0));
305 }
306
307 #[test]
308 fn test_display_human_readable() {
309 let future = Future::<CurrentNetwork>::new(
311 crate::ProgramID::from_str("credits.aleo").unwrap(),
312 crate::Identifier::from_str("transfer").unwrap(),
313 vec![],
314 );
315
316 let dynamic = DynamicFuture::from_future(&future).unwrap();
318
319 let display = dynamic.to_string();
321 assert!(display.contains("_program_id:"));
322 assert!(display.contains("credits.aleo"));
323 assert!(display.contains("_function_name:"));
324 assert!(display.contains("transfer"));
325 assert!(display.contains("_checksum:"));
326 }
327
328 #[test]
329 fn test_display_fallback_to_raw() {
330 let dynamic = DynamicFuture::<CurrentNetwork>::new_unchecked(
332 Field::from_u64(u64::MAX),
333 Field::from_u64(u64::MAX),
334 Field::from_u64(u64::MAX),
335 Field::from_u64(0),
336 None,
337 );
338
339 let display = dynamic.to_string();
341 assert!(display.contains("_program_name:"));
342 assert!(display.contains("_program_network:"));
343 assert!(display.contains("_function_name:"));
344 assert!(display.contains("_checksum:"));
345 }
346}