snarkvm_console_program/data/literal/
parse.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM 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
16use super::*;
17
18impl<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
46impl<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
64impl<N: Network> Debug for Literal<N> {
65    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
66        Display::fmt(self, f)
67    }
68}
69
70impl<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)]
95mod tests {
96    use super::*;
97    use snarkvm_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.aleo")?;
104        assert!(matches!(candidate, Literal::Address(_)));
105        assert_eq!(candidate.to_string(), "aleo1lqmly7ez2k48ajf5hs92ulphaqr05qm4n8qwzj8v0yprmasgpqgsez59gg");
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.aleo1");
112        assert!(result.is_err());
113
114        Ok(())
115    }
116}