snarkvm_console_program/data/value/
parse.rs1use super::*;
17
18impl<N: Network> Parser for Value<N> {
19 #[inline]
21 fn parse(string: &str) -> ParserResult<Self> {
22 alt((
24 map(Future::parse, Value::Future),
25 map(DynamicFuture::parse, Value::DynamicFuture),
26 map(Plaintext::parse, Value::Plaintext),
27 map(Record::parse, Value::Record),
28 map(DynamicRecord::parse, Value::DynamicRecord),
29 ))(string)
30 }
31}
32
33impl<N: Network> FromStr for Value<N> {
34 type Err = Error;
35
36 #[inline]
38 fn from_str(string: &str) -> Result<Self> {
39 match Self::parse(string) {
40 Ok((remainder, object)) => {
41 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
43 Ok(object)
45 }
46 Err(error) => bail!("Failed to parse string. {error}"),
47 }
48 }
49}
50
51impl<N: Network> Debug for Value<N> {
52 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
54 Display::fmt(self, f)
55 }
56}
57
58impl<N: Network> Display for Value<N> {
59 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
61 match self {
62 Value::Plaintext(plaintext) => Display::fmt(plaintext, f),
63 Value::Record(record) => Display::fmt(record, f),
64 Value::Future(future) => Display::fmt(future, f),
65 Value::DynamicRecord(dynamic_record) => Display::fmt(dynamic_record, f),
66 Value::DynamicFuture(dynamic_future) => Display::fmt(dynamic_future, f),
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::{Argument, Entry, Identifier, Literal, Owner, ProgramID};
75 use snarkvm_console_network::MainnetV0;
76 use snarkvm_console_types::{Group, U8, U64};
77 use snarkvm_utilities::{TestRng, Uniform};
78
79 type CurrentNetwork = MainnetV0;
80
81 #[test]
82 fn test_value_plaintext_parse() {
83 let string = r"{
85 owner: aleo1d5hg2z3ma00382pngntdp68e74zv54jdxy249qhaujhks9c72yrs33ddah,
86 token_amount: 100u64
87}";
88 let expected = Value::<CurrentNetwork>::from_str(string).unwrap();
90 assert!(matches!(expected, Value::Plaintext(..)));
91 assert_eq!(string, format!("{expected}"));
92 }
93
94 #[test]
95 fn test_value_record_parse() {
96 let string = r"{
98 owner: aleo1d5hg2z3ma00382pngntdp68e74zv54jdxy249qhaujhks9c72yrs33ddah.private,
99 token_amount: 100u64.private,
100 _nonce: 6122363155094913586073041054293642159180066699840940609722305038224296461351group.public,
101 _version: 0u8.public
102}";
103 let expected = Value::<CurrentNetwork>::from_str(string).unwrap();
105 assert!(matches!(expected, Value::Record(..)));
106 assert_eq!(string, format!("{expected}"));
107 }
108
109 #[test]
110 fn test_value_future_parse() {
111 let string = r"{
113 program_id: credits.aleo,
114 function_name: transfer_public_to_private,
115 arguments: [
116 aleo1g8qul5a44vk22u9uuvaewdcjw4v6xg8wx0llru39nnjn7eu08yrscxe4e2,
117 100000000u64
118 ]
119}";
120 let expected = Value::<CurrentNetwork>::from_str(string).unwrap();
122 assert!(matches!(expected, Value::Future(..)));
123 assert_eq!(string, format!("{expected}"));
124 }
125
126 #[test]
127 fn test_value_dynamic_record_parse() {
128 let rng = &mut TestRng::default();
129
130 let data = indexmap::indexmap! {
132 Identifier::from_str("amount").unwrap() => Entry::Private(Plaintext::from(Literal::U64(U64::rand(rng)))),
133 };
134 let owner = Owner::Public(Address::rand(rng));
135 let record = Record::<CurrentNetwork, Plaintext<CurrentNetwork>>::from_plaintext(
136 owner,
137 data,
138 Group::rand(rng),
139 U8::new(0),
140 )
141 .unwrap();
142 let expected = DynamicRecord::from_record(&record).unwrap();
143
144 let string = Value::DynamicRecord(expected.clone()).to_string();
146 let Value::DynamicRecord(candidate) = Value::<CurrentNetwork>::from_str(&string).unwrap() else {
147 panic!("Expected DynamicRecord value");
148 };
149
150 assert_eq!(expected.owner(), candidate.owner());
152 assert_eq!(expected.root(), candidate.root());
153 assert_eq!(expected.nonce(), candidate.nonce());
154 assert_eq!(expected.version(), candidate.version());
155 }
156
157 #[test]
158 fn test_value_dynamic_future_parse() {
159 let future = Future::<CurrentNetwork>::new(
161 ProgramID::from_str("test.aleo").unwrap(),
162 Identifier::from_str("foo").unwrap(),
163 vec![Argument::Plaintext(Plaintext::from_str("100u64").unwrap())],
164 );
165 let expected = DynamicFuture::from_future(&future).unwrap();
166
167 let string = Value::DynamicFuture(expected.clone()).to_string();
169 let Value::DynamicFuture(candidate) = Value::<CurrentNetwork>::from_str(&string).unwrap() else {
170 panic!("Expected DynamicFuture value");
171 };
172
173 assert_eq!(expected.program_name(), candidate.program_name());
175 assert_eq!(expected.program_network(), candidate.program_network());
176 assert_eq!(expected.function_name(), candidate.function_name());
177 assert_eq!(expected.checksum(), candidate.checksum());
178 }
179}