Skip to main content

snarkvm_console_program/data/literal/
parse.rs

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