/ console / program / src / data / literal / parse.rs
parse.rs
  1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
  2  // This file is part of the alphavm library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  use super::*;
 17  
 18  impl<N: Network> Parser for Literal<N> {
 19      /// Parses a string into a literal.
 20      #[inline]
 21      fn parse(string: &str) -> ParserResult<Self> {
 22          alt((
 23              map(Address::<N>::parse, |literal| Self::Address(literal)),
 24              map(Boolean::<N>::parse, |literal| Self::Boolean(literal)),
 25              map(Field::<N>::parse, |literal| Self::Field(literal)),
 26              map(Group::<N>::parse, |literal| Self::Group(literal)),
 27              map(I8::<N>::parse, |literal| Self::I8(literal)),
 28              map(I16::<N>::parse, |literal| Self::I16(literal)),
 29              map(I32::<N>::parse, |literal| Self::I32(literal)),
 30              map(I64::<N>::parse, |literal| Self::I64(literal)),
 31              map(I128::<N>::parse, |literal| Self::I128(literal)),
 32              map(U8::<N>::parse, |literal| Self::U8(literal)),
 33              map(U16::<N>::parse, |literal| Self::U16(literal)),
 34              map(U32::<N>::parse, |literal| Self::U32(literal)),
 35              map(U64::<N>::parse, |literal| Self::U64(literal)),
 36              map(U128::<N>::parse, |literal| Self::U128(literal)),
 37              map(Scalar::<N>::parse, |literal| Self::Scalar(literal)),
 38              map(Signature::<N>::parse, |literal| Self::Signature(Box::new(literal))),
 39              map(StringType::<N>::parse, |literal| Self::String(literal)),
 40              // This allows users to implicitly declare program IDs as literals.
 41              map_res(ProgramID::<N>::parse, |program_id| Ok::<Self, Error>(Self::Address(program_id.to_address()?))),
 42          ))(string)
 43      }
 44  }
 45  
 46  impl<N: Network> FromStr for Literal<N> {
 47      type Err = Error;
 48  
 49      /// Parses a string into a literal.
 50      #[inline]
 51      fn from_str(string: &str) -> Result<Self> {
 52          match Self::parse(string) {
 53              Ok((remainder, object)) => {
 54                  // Ensure the remainder is empty.
 55                  ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
 56                  // Return the object.
 57                  Ok(object)
 58              }
 59              Err(error) => bail!("Failed to parse string. {error}"),
 60          }
 61      }
 62  }
 63  
 64  impl<N: Network> Debug for Literal<N> {
 65      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 66          Display::fmt(self, f)
 67      }
 68  }
 69  
 70  impl<N: Network> Display for Literal<N> {
 71      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
 72          match self {
 73              Self::Address(literal) => Display::fmt(literal, f),
 74              Self::Boolean(literal) => Display::fmt(literal, f),
 75              Self::Field(literal) => Display::fmt(literal, f),
 76              Self::Group(literal) => Display::fmt(literal, f),
 77              Self::I8(literal) => Display::fmt(literal, f),
 78              Self::I16(literal) => Display::fmt(literal, f),
 79              Self::I32(literal) => Display::fmt(literal, f),
 80              Self::I64(literal) => Display::fmt(literal, f),
 81              Self::I128(literal) => Display::fmt(literal, f),
 82              Self::U8(literal) => Display::fmt(literal, f),
 83              Self::U16(literal) => Display::fmt(literal, f),
 84              Self::U32(literal) => Display::fmt(literal, f),
 85              Self::U64(literal) => Display::fmt(literal, f),
 86              Self::U128(literal) => Display::fmt(literal, f),
 87              Self::Scalar(literal) => Display::fmt(literal, f),
 88              Self::Signature(literal) => Display::fmt(literal, f),
 89              Self::String(literal) => Display::fmt(literal, f),
 90          }
 91      }
 92  }
 93  
 94  #[cfg(test)]
 95  mod tests {
 96      use super::*;
 97      use alphavm_console_network::MainnetV0;
 98  
 99      type CurrentNetwork = MainnetV0;
100  
101      #[test]
102      fn test_parse_program_id() -> Result<()> {
103          let (remainder, candidate) = Literal::<CurrentNetwork>::parse("credits.alpha")?;
104          assert!(matches!(candidate, Literal::Address(_)));
105          assert_eq!(candidate.to_string(), "ax1sj8u0j3eca65r9s5xma3rnvapcypgj78xnw3g6zf397dz3845ugq8d2jff");
106          assert_eq!("", remainder);
107  
108          let result = Literal::<CurrentNetwork>::parse("credits.ale");
109          assert!(result.is_err());
110  
111          let result = Literal::<CurrentNetwork>::parse("credits.ax1");
112          assert!(result.is_err());
113  
114          Ok(())
115      }
116  }