snarkvm_console_types_group/
parse.rs1use super::*;
17
18impl<E: Environment> Parser for Group<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, group): (&str, Self) = map_res(tag(Self::type_name()), |_| {
28 let x_coordinate = primitive.replace('_', "").parse()?;
29 match negation {
31 true => Ok(-Group::from_x_coordinate(Field::new(x_coordinate))?),
32 false => Group::from_x_coordinate(Field::new(x_coordinate)),
33 }
34 })(string)?;
35
36 Ok((string, group))
37 }
38}
39
40impl<E: Environment> FromStr for Group<E> {
41 type Err = Error;
42
43 #[inline]
45 fn from_str(string: &str) -> Result<Self> {
46 match Self::parse(string) {
47 Ok((remainder, object)) => {
48 ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
50 Ok(object)
52 }
53 Err(error) => bail!("Failed to parse string. {error}"),
54 }
55 }
56}
57
58impl<E: Environment> Debug for Group<E> {
59 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
60 Display::fmt(self, f)
61 }
62}
63
64impl<E: Environment> Display for Group<E> {
65 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
66 write!(f, "{}{}", self.group.to_affine().to_x_coordinate(), Self::type_name())
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use snarkvm_console_network_environment::Console;
74
75 type CurrentEnvironment = Console;
76
77 const ITERATIONS: u64 = 1_000;
78
79 #[test]
80 fn test_parse() -> Result<()> {
81 let rng = &mut TestRng::default();
82
83 assert!(Group::<CurrentEnvironment>::parse(Group::<CurrentEnvironment>::type_name()).is_err());
85 assert!(Group::<CurrentEnvironment>::parse("").is_err());
86
87 for _ in 0..ITERATIONS {
88 let group: <CurrentEnvironment as Environment>::Affine = Uniform::rand(rng);
90
91 let expected = format!("{}{}", group.to_x_coordinate(), Group::<CurrentEnvironment>::type_name());
92 let (remainder, candidate) = Group::<CurrentEnvironment>::parse(&expected).unwrap();
93 assert_eq!(format!("{expected}"), candidate.to_string());
94 assert_eq!("", remainder);
95 }
96 Ok(())
97 }
98
99 #[test]
100 fn test_display() {
101 fn check_display<E: Environment>(element: E::Affine) {
104 let candidate = Group::<E>::new(element);
105 assert_eq!(format!("{}{}", element.to_x_coordinate(), Group::<E>::type_name()), format!("{candidate}"));
106
107 let candidate_recovered = Group::<E>::from_str(&format!("{candidate}")).unwrap();
108 assert_eq!(candidate, candidate_recovered);
109 }
110
111 let mut rng = TestRng::default();
112
113 for _ in 0..ITERATIONS {
114 let element = Uniform::rand(&mut rng);
115
116 check_display::<CurrentEnvironment>(element);
117 }
118 }
119
120 #[test]
121 fn test_display_zero() {
122 let zero = <CurrentEnvironment as Environment>::Affine::zero();
123
124 let candidate = Group::<CurrentEnvironment>::new(zero);
125 assert_eq!("0group", &format!("{candidate}"));
126 }
127}