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 ValueType<N> {
 22      /// Parses the string into a value type.
 23      #[inline]
 24      fn parse(string: &str) -> ParserResult<'_, Self> {
 25          // Parse the mode from the string.
 26          // Note that the order of the parsers matters.
 27          alt((
 28              map(pair(PlaintextType::parse, tag(".constant")), |(plaintext_type, _)| Self::Constant(plaintext_type)),
 29              map(pair(PlaintextType::parse, tag(".public")), |(plaintext_type, _)| Self::Public(plaintext_type)),
 30              map(pair(PlaintextType::parse, tag(".private")), |(plaintext_type, _)| Self::Private(plaintext_type)),
 31              map(pair(Identifier::parse, tag(".record")), |(identifier, _)| Self::Record(identifier)),
 32              map(pair(Locator::parse, tag(".record")), |(locator, _)| Self::ExternalRecord(locator)),
 33              map(pair(Locator::parse, tag(".future")), |(locator, _)| Self::Future(locator)),
 34          ))(string)
 35      }
 36  }
 37  
 38  impl<N: Network> FromStr for ValueType<N> {
 39      type Err = Error;
 40  
 41      /// Returns the value type from a string literal.
 42      fn from_str(string: &str) -> Result<Self> {
 43          match Self::parse(string) {
 44              Ok((remainder, object)) => {
 45                  // Ensure the remainder is empty.
 46                  ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
 47                  // Return the object.
 48                  Ok(object)
 49              }
 50              Err(error) => bail!("Failed to parse string. {error}"),
 51          }
 52      }
 53  }
 54  
 55  impl<N: Network> Debug for ValueType<N> {
 56      /// Prints the value type as a string.
 57      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 58          Display::fmt(self, f)
 59      }
 60  }
 61  
 62  impl<N: Network> Display for ValueType<N> {
 63      /// Prints the value type as a string.
 64      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 65          match self {
 66              Self::Constant(plaintext_type) => write!(f, "{plaintext_type}.constant"),
 67              Self::Public(plaintext_type) => write!(f, "{plaintext_type}.public"),
 68              Self::Private(plaintext_type) => write!(f, "{plaintext_type}.private"),
 69              Self::Record(identifier) => write!(f, "{identifier}.record"),
 70              Self::ExternalRecord(locator) => write!(f, "{locator}.record"),
 71              Self::Future(locator) => write!(f, "{locator}.future"),
 72          }
 73      }
 74  }
 75  
 76  #[cfg(test)]
 77  mod tests {
 78      use super::*;
 79      use alphavm_console_network::MainnetV0;
 80  
 81      type CurrentNetwork = MainnetV0;
 82  
 83      #[test]
 84      fn test_parse() -> Result<()> {
 85          // Literal type.
 86          assert_eq!(
 87              Ok(("", ValueType::<CurrentNetwork>::from_str("field.constant")?)),
 88              ValueType::<CurrentNetwork>::parse("field.constant")
 89          );
 90          assert_eq!(
 91              Ok(("", ValueType::<CurrentNetwork>::from_str("field.public")?)),
 92              ValueType::<CurrentNetwork>::parse("field.public")
 93          );
 94          assert_eq!(
 95              Ok(("", ValueType::<CurrentNetwork>::from_str("field.private")?)),
 96              ValueType::<CurrentNetwork>::parse("field.private")
 97          );
 98  
 99          // Struct type.
100          assert_eq!(
101              Ok(("", ValueType::<CurrentNetwork>::from_str("signature.constant")?)),
102              ValueType::<CurrentNetwork>::parse("signature.constant")
103          );
104          assert_eq!(
105              Ok(("", ValueType::<CurrentNetwork>::from_str("signature.public")?)),
106              ValueType::<CurrentNetwork>::parse("signature.public")
107          );
108          assert_eq!(
109              Ok(("", ValueType::<CurrentNetwork>::from_str("signature.private")?)),
110              ValueType::<CurrentNetwork>::parse("signature.private")
111          );
112          assert_eq!(
113              Ok(("", ValueType::<CurrentNetwork>::from_str("i8abc.constant")?)),
114              ValueType::<CurrentNetwork>::parse("i8abc.constant")
115          );
116  
117          // Record type.
118          assert_eq!(
119              Ok(("", ValueType::<CurrentNetwork>::from_str("token.record")?)),
120              ValueType::<CurrentNetwork>::parse("token.record")
121          );
122          assert_eq!(
123              ValueType::<CurrentNetwork>::Record(Identifier::from_str("message")?),
124              ValueType::<CurrentNetwork>::parse("message.record")?.1
125          );
126  
127          // ExternalRecord type.
128          assert_eq!(
129              Ok(("", ValueType::<CurrentNetwork>::from_str("howard.alpha/message.record")?)),
130              ValueType::<CurrentNetwork>::parse("howard.alpha/message.record")
131          );
132          assert_eq!(
133              ValueType::<CurrentNetwork>::ExternalRecord(Locator::from_str("howard.alpha/message")?),
134              ValueType::<CurrentNetwork>::parse("howard.alpha/message.record")?.1
135          );
136  
137          // Future type.
138          assert_eq!(
139              Ok(("", ValueType::<CurrentNetwork>::from_str("credits.alpha/mint_public.future")?)),
140              ValueType::<CurrentNetwork>::parse("credits.alpha/mint_public.future")
141          );
142          assert_eq!(
143              ValueType::<CurrentNetwork>::Future(Locator::from_str("credits.alpha/mint_public")?),
144              ValueType::<CurrentNetwork>::parse("credits.alpha/mint_public.future")?.1
145          );
146  
147          Ok(())
148      }
149  
150      #[test]
151      fn test_parse_fails() -> Result<()> {
152          // Literal type must contain visibility.
153          assert!(ValueType::<CurrentNetwork>::parse("field").is_err());
154          // Struct type must contain visibility.
155          assert!(ValueType::<CurrentNetwork>::parse("signature").is_err());
156          // Record type must contain record keyword.
157          assert!(ValueType::<CurrentNetwork>::parse("token").is_err());
158  
159          // Must be non-empty.
160          assert!(ValueType::<CurrentNetwork>::parse("").is_err());
161  
162          // Invalid characters.
163          assert!(ValueType::<CurrentNetwork>::parse("{}").is_err());
164          assert!(ValueType::<CurrentNetwork>::parse("_").is_err());
165          assert!(ValueType::<CurrentNetwork>::parse("__").is_err());
166          assert!(ValueType::<CurrentNetwork>::parse("___").is_err());
167          assert!(ValueType::<CurrentNetwork>::parse("-").is_err());
168          assert!(ValueType::<CurrentNetwork>::parse("--").is_err());
169          assert!(ValueType::<CurrentNetwork>::parse("---").is_err());
170          assert!(ValueType::<CurrentNetwork>::parse("*").is_err());
171          assert!(ValueType::<CurrentNetwork>::parse("**").is_err());
172          assert!(ValueType::<CurrentNetwork>::parse("***").is_err());
173  
174          // Must not start with a number.
175          assert!(ValueType::<CurrentNetwork>::parse("1").is_err());
176          assert!(ValueType::<CurrentNetwork>::parse("2").is_err());
177          assert!(ValueType::<CurrentNetwork>::parse("3").is_err());
178          assert!(ValueType::<CurrentNetwork>::parse("1foo").is_err());
179          assert!(ValueType::<CurrentNetwork>::parse("12").is_err());
180          assert!(ValueType::<CurrentNetwork>::parse("111").is_err());
181  
182          // Must fit within the data capacity of a base field element.
183          let struct_ = ValueType::<CurrentNetwork>::parse(
184              "foo_bar_baz_qux_quux_quuz_corge_grault_garply_waldo_fred_plugh_xyzzy.private",
185          );
186          assert!(struct_.is_err());
187  
188          Ok(())
189      }
190  
191      #[test]
192      fn test_display() -> Result<()> {
193          assert_eq!(ValueType::<CurrentNetwork>::from_str("field.constant")?.to_string(), "field.constant");
194          assert_eq!(ValueType::<CurrentNetwork>::from_str("field.public")?.to_string(), "field.public");
195          assert_eq!(ValueType::<CurrentNetwork>::from_str("field.private")?.to_string(), "field.private");
196  
197          assert_eq!(ValueType::<CurrentNetwork>::from_str("signature.constant")?.to_string(), "signature.constant");
198          assert_eq!(ValueType::<CurrentNetwork>::from_str("signature.public")?.to_string(), "signature.public");
199          assert_eq!(ValueType::<CurrentNetwork>::from_str("signature.private")?.to_string(), "signature.private");
200  
201          assert_eq!(ValueType::<CurrentNetwork>::from_str("token.record")?.to_string(), "token.record");
202  
203          assert_eq!(
204              ValueType::<CurrentNetwork>::from_str("howard.alpha/message.record")?.to_string(),
205              "howard.alpha/message.record"
206          );
207  
208          Ok(())
209      }
210  }