snarkvm_console_types_field/
parse.rs1use super::*;
17
18impl<E: Environment> Parser for Field<E> {
19 #[inline]
21 fn parse(string: &str) -> ParserResult<Self> {
22 let (string, negation) = map(opt(tag("-")), |neg: Option<&str>| neg.is_some())(string)?;
24 let (string, primitive) = recognize(many1(terminated(one_of("0123456789"), many0(char('_')))))(string)?;
26 let (string, value): (&str, E::Field) =
28 map_res(tag(Self::type_name()), |_| primitive.replace('_', "").parse())(string)?;
29 let value = match negation {
31 true => -value,
32 false => value,
33 };
34
35 Ok((string, Field::new(value)))
36 }
37}
38
39impl<E: Environment> FromStr for Field<E> {
40 type Err = Error;
41
42 #[inline]
44 fn from_str(string: &str) -> Result<Self> {
45 match Self::parse(string) {
46 Ok((remainder, object)) => {
47 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
49 Ok(object)
51 }
52 Err(error) => bail!("Failed to parse string. {error}"),
53 }
54 }
55}
56
57impl<E: Environment> Debug for Field<E> {
58 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
59 Display::fmt(self, f)
60 }
61}
62
63impl<E: Environment> Display for Field<E> {
64 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
65 write!(f, "{}{}", self.field, Self::type_name())
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use snarkvm_console_network_environment::Console;
73
74 type CurrentEnvironment = Console;
75
76 const ITERATIONS: u64 = 10_000;
77
78 #[test]
79 fn test_parse() -> Result<()> {
80 let rng = &mut TestRng::default();
81
82 assert!(Field::<CurrentEnvironment>::parse(Field::<CurrentEnvironment>::type_name()).is_err());
84 assert!(Field::<CurrentEnvironment>::parse("").is_err());
85
86 for _ in 0..ITERATIONS {
87 let field: <CurrentEnvironment as Environment>::Field = Uniform::rand(rng);
89
90 let expected = format!("{}{}", field, Field::<CurrentEnvironment>::type_name());
91 let (remainder, candidate) = Field::<CurrentEnvironment>::parse(&expected).unwrap();
92 assert_eq!(format!("{expected}"), candidate.to_string());
93 assert_eq!("", remainder);
94 }
95 Ok(())
96 }
97
98 #[test]
99 fn test_display() {
100 fn check_display<E: Environment>(element: E::Field) {
103 let candidate = Field::<E>::new(element);
104 assert_eq!(format!("{element}{}", Field::<E>::type_name()), format!("{candidate}"));
105
106 let candidate_recovered = Field::<E>::from_str(&format!("{candidate}")).unwrap();
107 assert_eq!(candidate, candidate_recovered);
108 }
109
110 let mut rng = TestRng::default();
111
112 for _ in 0..ITERATIONS {
113 let element = Uniform::rand(&mut rng);
114
115 check_display::<CurrentEnvironment>(element);
116 }
117 }
118
119 #[test]
120 fn test_display_zero() {
121 let zero = <CurrentEnvironment as Environment>::Field::zero();
122
123 let candidate = Field::<CurrentEnvironment>::new(zero);
124 assert_eq!("0field", &format!("{candidate}"));
125 }
126
127 #[test]
128 fn test_display_one() {
129 let one = <CurrentEnvironment as Environment>::Field::one();
130
131 let candidate = Field::<CurrentEnvironment>::new(one);
132 assert_eq!("1field", &format!("{candidate}"));
133 }
134
135 #[test]
136 fn test_display_two() {
137 let one = <CurrentEnvironment as Environment>::Field::one();
138 let two = one + one;
139
140 let candidate = Field::<CurrentEnvironment>::new(two);
141 assert_eq!("2field", &format!("{candidate}"));
142 }
143}