parse.rs
  1  // Copyright (c) 2025-2026 ACDC Network
  2  // This file is part of the alphavm library.
  3  //
  4  // Alpha Chain | Delta Chain Protocol
  5  // International Monetary Graphite.
  6  //
  7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
  8  // They built world-class ZK infrastructure. We installed the EASY button.
  9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
 10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
 11  //
 12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
 13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
 14  // No rights reserved. No permission required. No warranty. No refunds.
 15  //
 16  // https://creativecommons.org/publicdomain/zero/1.0/
 17  // SPDX-License-Identifier: CC0-1.0
 18  
 19  use super::*;
 20  
 21  impl<N: Network> Parser for RegisterType<N> {
 22      /// Parses a string into a register type.
 23      #[inline]
 24      fn parse(string: &str) -> ParserResult<'_, Self> {
 25          // Parse the mode from the string (ordering matters).
 26          alt((
 27              map(pair(Locator::parse, tag(".future")), |(locator, _)| Self::Future(locator)),
 28              map(pair(Locator::parse, tag(".record")), |(locator, _)| Self::ExternalRecord(locator)),
 29              map(pair(Identifier::parse, tag(".record")), |(identifier, _)| Self::Record(identifier)),
 30              map(PlaintextType::parse, |plaintext_type| Self::Plaintext(plaintext_type)),
 31          ))(string)
 32      }
 33  }
 34  
 35  impl<N: Network> FromStr for RegisterType<N> {
 36      type Err = Error;
 37  
 38      /// Returns a register type from a string literal.
 39      fn from_str(string: &str) -> Result<Self> {
 40          match Self::parse(string) {
 41              Ok((remainder, object)) => {
 42                  // Ensure the remainder is empty.
 43                  ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
 44                  // Return the object.
 45                  Ok(object)
 46              }
 47              Err(error) => bail!("Failed to parse string. {error}"),
 48          }
 49      }
 50  }
 51  
 52  impl<N: Network> Debug for RegisterType<N> {
 53      /// Prints the register type as a string.
 54      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 55          Display::fmt(self, f)
 56      }
 57  }
 58  
 59  impl<N: Network> Display for RegisterType<N> {
 60      /// Prints the register type as a string.
 61      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 62          match self {
 63              // Prints the plaintext type, i.e. signature
 64              Self::Plaintext(plaintext_type) => write!(f, "{plaintext_type}"),
 65              // Prints the record name, i.e. token.record
 66              Self::Record(record_name) => write!(f, "{record_name}.record"),
 67              // Prints the locator, i.e. token.alpha/token.record
 68              Self::ExternalRecord(locator) => write!(f, "{locator}.record"),
 69              // Prints the future type, i.e. future
 70              Self::Future(locator) => write!(f, "{locator}.future"),
 71          }
 72      }
 73  }
 74  
 75  #[cfg(test)]
 76  mod tests {
 77      use super::*;
 78      use alphavm_console_network::MainnetV0;
 79  
 80      type CurrentNetwork = MainnetV0;
 81  
 82      #[test]
 83      fn test_parse() -> Result<()> {
 84          // Literal type.
 85          assert_eq!(
 86              Ok(("", RegisterType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("field")?))),
 87              RegisterType::<CurrentNetwork>::parse("field")
 88          );
 89  
 90          // Struct type.
 91          assert_eq!(
 92              Ok(("", RegisterType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("signature")?))),
 93              RegisterType::<CurrentNetwork>::parse("signature")
 94          );
 95          assert_eq!(
 96              Ok(("", RegisterType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("u8kldsafj")?))),
 97              RegisterType::<CurrentNetwork>::parse("u8kldsafj")
 98          );
 99  
100          // Record type.
101          assert_eq!(
102              Ok(("", RegisterType::<CurrentNetwork>::Record(Identifier::from_str("token")?))),
103              RegisterType::<CurrentNetwork>::parse("token.record")
104          );
105  
106          // ExternalRecord type.
107          assert_eq!(
108              Ok(("", RegisterType::<CurrentNetwork>::ExternalRecord(Locator::from_str("token.alpha/token")?))),
109              RegisterType::<CurrentNetwork>::parse("token.alpha/token.record")
110          );
111  
112          Ok(())
113      }
114  
115      #[test]
116      fn test_parse_fails() -> Result<()> {
117          // Must be non-empty.
118          assert!(RegisterType::<CurrentNetwork>::parse("").is_err());
119  
120          // Invalid characters.
121          assert!(RegisterType::<CurrentNetwork>::parse("{}").is_err());
122          assert!(RegisterType::<CurrentNetwork>::parse("_").is_err());
123          assert!(RegisterType::<CurrentNetwork>::parse("__").is_err());
124          assert!(RegisterType::<CurrentNetwork>::parse("___").is_err());
125          assert!(RegisterType::<CurrentNetwork>::parse("-").is_err());
126          assert!(RegisterType::<CurrentNetwork>::parse("--").is_err());
127          assert!(RegisterType::<CurrentNetwork>::parse("---").is_err());
128          assert!(RegisterType::<CurrentNetwork>::parse("*").is_err());
129          assert!(RegisterType::<CurrentNetwork>::parse("**").is_err());
130          assert!(RegisterType::<CurrentNetwork>::parse("***").is_err());
131  
132          // Must not start with a number.
133          assert!(RegisterType::<CurrentNetwork>::parse("1").is_err());
134          assert!(RegisterType::<CurrentNetwork>::parse("2").is_err());
135          assert!(RegisterType::<CurrentNetwork>::parse("3").is_err());
136          assert!(RegisterType::<CurrentNetwork>::parse("1foo").is_err());
137          assert!(RegisterType::<CurrentNetwork>::parse("12").is_err());
138          assert!(RegisterType::<CurrentNetwork>::parse("111").is_err());
139  
140          // Must fit within the data capacity of a base field element.
141          let struct_ = RegisterType::<CurrentNetwork>::parse(
142              "foo_bar_baz_qux_quux_quuz_corge_grault_garply_waldo_fred_plugh_xyzzy.private",
143          );
144          assert!(struct_.is_err());
145  
146          Ok(())
147      }
148  
149      #[test]
150      fn test_display() -> Result<()> {
151          assert_eq!(RegisterType::<CurrentNetwork>::from_str("field")?.to_string(), "field");
152          assert_eq!(RegisterType::<CurrentNetwork>::from_str("signature")?.to_string(), "signature");
153          assert_eq!(RegisterType::<CurrentNetwork>::from_str("token.record")?.to_string(), "token.record");
154          assert_eq!(
155              RegisterType::<CurrentNetwork>::from_str("token.alpha/token.record")?.to_string(),
156              "token.alpha/token.record"
157          );
158          Ok(())
159      }
160  }