/ console / program / src / data / literal / parse.rs
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 Literal<N> {
 22      /// Parses a string into a literal.
 23      #[inline]
 24      fn parse(string: &str) -> ParserResult<'_, Self> {
 25          alt((
 26              map(Address::<N>::parse, |literal| Self::Address(literal)),
 27              map(Boolean::<N>::parse, |literal| Self::Boolean(literal)),
 28              map(Field::<N>::parse, |literal| Self::Field(literal)),
 29              map(Group::<N>::parse, |literal| Self::Group(literal)),
 30              map(I8::<N>::parse, |literal| Self::I8(literal)),
 31              map(I16::<N>::parse, |literal| Self::I16(literal)),
 32              map(I32::<N>::parse, |literal| Self::I32(literal)),
 33              map(I64::<N>::parse, |literal| Self::I64(literal)),
 34              map(I128::<N>::parse, |literal| Self::I128(literal)),
 35              map(U8::<N>::parse, |literal| Self::U8(literal)),
 36              map(U16::<N>::parse, |literal| Self::U16(literal)),
 37              map(U32::<N>::parse, |literal| Self::U32(literal)),
 38              map(U64::<N>::parse, |literal| Self::U64(literal)),
 39              map(U128::<N>::parse, |literal| Self::U128(literal)),
 40              map(Scalar::<N>::parse, |literal| Self::Scalar(literal)),
 41              map(Signature::<N>::parse, |literal| Self::Signature(Box::new(literal))),
 42              map(StringType::<N>::parse, |literal| Self::String(literal)),
 43              // This allows users to implicitly declare program IDs as literals.
 44              map_res(ProgramID::<N>::parse, |program_id| Ok::<Self, Error>(Self::Address(program_id.to_address()?))),
 45          ))(string)
 46      }
 47  }
 48  
 49  impl<N: Network> FromStr for Literal<N> {
 50      type Err = Error;
 51  
 52      /// Parses a string into a literal.
 53      #[inline]
 54      fn from_str(string: &str) -> Result<Self> {
 55          match Self::parse(string) {
 56              Ok((remainder, object)) => {
 57                  // Ensure the remainder is empty.
 58                  ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
 59                  // Return the object.
 60                  Ok(object)
 61              }
 62              Err(error) => bail!("Failed to parse string. {error}"),
 63          }
 64      }
 65  }
 66  
 67  impl<N: Network> Debug for Literal<N> {
 68      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 69          Display::fmt(self, f)
 70      }
 71  }
 72  
 73  impl<N: Network> Display for Literal<N> {
 74      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 75          match self {
 76              Self::Address(literal) => Display::fmt(literal, f),
 77              Self::Boolean(literal) => Display::fmt(literal, f),
 78              Self::Field(literal) => Display::fmt(literal, f),
 79              Self::Group(literal) => Display::fmt(literal, f),
 80              Self::I8(literal) => Display::fmt(literal, f),
 81              Self::I16(literal) => Display::fmt(literal, f),
 82              Self::I32(literal) => Display::fmt(literal, f),
 83              Self::I64(literal) => Display::fmt(literal, f),
 84              Self::I128(literal) => Display::fmt(literal, f),
 85              Self::U8(literal) => Display::fmt(literal, f),
 86              Self::U16(literal) => Display::fmt(literal, f),
 87              Self::U32(literal) => Display::fmt(literal, f),
 88              Self::U64(literal) => Display::fmt(literal, f),
 89              Self::U128(literal) => Display::fmt(literal, f),
 90              Self::Scalar(literal) => Display::fmt(literal, f),
 91              Self::Signature(literal) => Display::fmt(literal, f),
 92              Self::String(literal) => Display::fmt(literal, f),
 93          }
 94      }
 95  }
 96  
 97  #[cfg(test)]
 98  mod tests {
 99      use super::*;
100      use alphavm_console_network::MainnetV0;
101  
102      type CurrentNetwork = MainnetV0;
103  
104      #[test]
105      fn test_parse_program_id() -> Result<()> {
106          let (remainder, candidate) = Literal::<CurrentNetwork>::parse("credits.alpha")?;
107          assert!(matches!(candidate, Literal::Address(_)));
108          assert_eq!(candidate.to_string(), "ax1sj8u0j3eca65r9s5xma3rnvapcypgj78xnw3g6zf397dz3845ugq8d2jff");
109          assert_eq!("", remainder);
110  
111          let result = Literal::<CurrentNetwork>::parse("credits.ale");
112          assert!(result.is_err());
113  
114          let result = Literal::<CurrentNetwork>::parse("credits.ax1");
115          assert!(result.is_err());
116  
117          Ok(())
118      }
119  }