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 }