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 FinalizeType<N> {
 22      /// Parses a string into a finalize 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(PlaintextType::parse, tag(".public")), |(plaintext_type, _)| Self::Plaintext(plaintext_type)),
 29          ))(string)
 30      }
 31  }
 32  
 33  impl<N: Network> FromStr for FinalizeType<N> {
 34      type Err = Error;
 35  
 36      /// Returns a finalize type from a string literal.
 37      fn from_str(string: &str) -> Result<Self> {
 38          match Self::parse(string) {
 39              Ok((remainder, object)) => {
 40                  // Ensure the remainder is empty.
 41                  ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
 42                  // Return the object.
 43                  Ok(object)
 44              }
 45              Err(error) => bail!("Failed to parse string. {error}"),
 46          }
 47      }
 48  }
 49  
 50  impl<N: Network> Debug for FinalizeType<N> {
 51      /// Prints the finalize type as a string.
 52      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 53          Display::fmt(self, f)
 54      }
 55  }
 56  
 57  impl<N: Network> Display for FinalizeType<N> {
 58      /// Prints the finalize type as a string.
 59      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 60          match self {
 61              // Prints the plaintext type, i.e. signature
 62              Self::Plaintext(plaintext_type) => write!(f, "{plaintext_type}.public"),
 63              // Prints the future type, i.e. future
 64              Self::Future(locator) => write!(f, "{locator}.future"),
 65          }
 66      }
 67  }
 68  
 69  #[cfg(test)]
 70  mod tests {
 71      use super::*;
 72      use alphavm_console_network::MainnetV0;
 73  
 74      type CurrentNetwork = MainnetV0;
 75  
 76      #[test]
 77      fn test_parse() -> Result<()> {
 78          // Literal type.
 79          assert_eq!(
 80              Ok(("", FinalizeType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("field")?))),
 81              FinalizeType::<CurrentNetwork>::parse("field.public")
 82          );
 83  
 84          // Struct type.
 85          assert_eq!(
 86              Ok(("", FinalizeType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("signature")?))),
 87              FinalizeType::<CurrentNetwork>::parse("signature.public")
 88          );
 89  
 90          // Future type.
 91          assert_eq!(
 92              Ok(("", FinalizeType::<CurrentNetwork>::Future(Locator::from_str("credits.alpha/mint_public")?))),
 93              FinalizeType::<CurrentNetwork>::parse("credits.alpha/mint_public.future")
 94          );
 95  
 96          Ok(())
 97      }
 98  
 99      #[test]
100      fn test_parse_fails() -> Result<()> {
101          // Must be non-empty.
102          assert!(FinalizeType::<CurrentNetwork>::parse("").is_err());
103  
104          // Invalid characters.
105          assert!(FinalizeType::<CurrentNetwork>::parse("{}").is_err());
106          assert!(FinalizeType::<CurrentNetwork>::parse("_").is_err());
107          assert!(FinalizeType::<CurrentNetwork>::parse("__").is_err());
108          assert!(FinalizeType::<CurrentNetwork>::parse("___").is_err());
109          assert!(FinalizeType::<CurrentNetwork>::parse("-").is_err());
110          assert!(FinalizeType::<CurrentNetwork>::parse("--").is_err());
111          assert!(FinalizeType::<CurrentNetwork>::parse("---").is_err());
112          assert!(FinalizeType::<CurrentNetwork>::parse("*").is_err());
113          assert!(FinalizeType::<CurrentNetwork>::parse("**").is_err());
114          assert!(FinalizeType::<CurrentNetwork>::parse("***").is_err());
115  
116          // Must not start with a number.
117          assert!(FinalizeType::<CurrentNetwork>::parse("1").is_err());
118          assert!(FinalizeType::<CurrentNetwork>::parse("2").is_err());
119          assert!(FinalizeType::<CurrentNetwork>::parse("3").is_err());
120          assert!(FinalizeType::<CurrentNetwork>::parse("1foo").is_err());
121          assert!(FinalizeType::<CurrentNetwork>::parse("12").is_err());
122          assert!(FinalizeType::<CurrentNetwork>::parse("111").is_err());
123  
124          // Must fit within the data capacity of a base field element.
125          let struct_ = FinalizeType::<CurrentNetwork>::parse(
126              "foo_bar_baz_qux_quux_quuz_corge_grault_garply_waldo_fred_plugh_xyzzy.private",
127          );
128          assert!(struct_.is_err());
129  
130          Ok(())
131      }
132  
133      #[test]
134      fn test_display() -> Result<()> {
135          assert_eq!(FinalizeType::<CurrentNetwork>::from_str("field.public")?.to_string(), "field.public");
136          assert_eq!(FinalizeType::<CurrentNetwork>::from_str("signature.public")?.to_string(), "signature.public");
137          assert_eq!(
138              FinalizeType::<CurrentNetwork>::from_str("credits.alpha/mint_public.future")?.to_string(),
139              "credits.alpha/mint_public.future"
140          );
141  
142          Ok(())
143      }
144  }