snarkvm_console_program/data_types/finalize_type/
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 FinalizeType<N> {
19    /// Parses a string into a finalize type.
20    #[inline]
21    fn parse(string: &str) -> ParserResult<Self> {
22        // Parse the mode from the string (ordering matters).
23        alt((
24            map(pair(Locator::parse, tag(".future")), |(locator, _)| Self::Future(locator)),
25            map(pair(PlaintextType::parse, tag(".public")), |(plaintext_type, _)| Self::Plaintext(plaintext_type)),
26        ))(string)
27    }
28}
29
30impl<N: Network> FromStr for FinalizeType<N> {
31    type Err = Error;
32
33    /// Returns a finalize type from a string literal.
34    fn from_str(string: &str) -> Result<Self> {
35        match Self::parse(string) {
36            Ok((remainder, object)) => {
37                // Ensure the remainder is empty.
38                ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
39                // Return the object.
40                Ok(object)
41            }
42            Err(error) => bail!("Failed to parse string. {error}"),
43        }
44    }
45}
46
47impl<N: Network> Debug for FinalizeType<N> {
48    /// Prints the finalize type as a string.
49    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
50        Display::fmt(self, f)
51    }
52}
53
54impl<N: Network> Display for FinalizeType<N> {
55    /// Prints the finalize type as a string.
56    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
57        match self {
58            // Prints the plaintext type, i.e. signature
59            Self::Plaintext(plaintext_type) => write!(f, "{plaintext_type}.public"),
60            // Prints the future type, i.e. future
61            Self::Future(locator) => write!(f, "{locator}.future"),
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use snarkvm_console_network::MainnetV0;
70
71    type CurrentNetwork = MainnetV0;
72
73    #[test]
74    fn test_parse() -> Result<()> {
75        // Literal type.
76        assert_eq!(
77            Ok(("", FinalizeType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("field")?))),
78            FinalizeType::<CurrentNetwork>::parse("field.public")
79        );
80
81        // Struct type.
82        assert_eq!(
83            Ok(("", FinalizeType::<CurrentNetwork>::Plaintext(PlaintextType::from_str("signature")?))),
84            FinalizeType::<CurrentNetwork>::parse("signature.public")
85        );
86
87        // Future type.
88        assert_eq!(
89            Ok(("", FinalizeType::<CurrentNetwork>::Future(Locator::from_str("credits.aleo/mint_public")?))),
90            FinalizeType::<CurrentNetwork>::parse("credits.aleo/mint_public.future")
91        );
92
93        Ok(())
94    }
95
96    #[test]
97    fn test_parse_fails() -> Result<()> {
98        // Must be non-empty.
99        assert!(FinalizeType::<CurrentNetwork>::parse("").is_err());
100
101        // Invalid characters.
102        assert!(FinalizeType::<CurrentNetwork>::parse("{}").is_err());
103        assert!(FinalizeType::<CurrentNetwork>::parse("_").is_err());
104        assert!(FinalizeType::<CurrentNetwork>::parse("__").is_err());
105        assert!(FinalizeType::<CurrentNetwork>::parse("___").is_err());
106        assert!(FinalizeType::<CurrentNetwork>::parse("-").is_err());
107        assert!(FinalizeType::<CurrentNetwork>::parse("--").is_err());
108        assert!(FinalizeType::<CurrentNetwork>::parse("---").is_err());
109        assert!(FinalizeType::<CurrentNetwork>::parse("*").is_err());
110        assert!(FinalizeType::<CurrentNetwork>::parse("**").is_err());
111        assert!(FinalizeType::<CurrentNetwork>::parse("***").is_err());
112
113        // Must not start with a number.
114        assert!(FinalizeType::<CurrentNetwork>::parse("1").is_err());
115        assert!(FinalizeType::<CurrentNetwork>::parse("2").is_err());
116        assert!(FinalizeType::<CurrentNetwork>::parse("3").is_err());
117        assert!(FinalizeType::<CurrentNetwork>::parse("1foo").is_err());
118        assert!(FinalizeType::<CurrentNetwork>::parse("12").is_err());
119        assert!(FinalizeType::<CurrentNetwork>::parse("111").is_err());
120
121        // Must fit within the data capacity of a base field element.
122        let struct_ = FinalizeType::<CurrentNetwork>::parse(
123            "foo_bar_baz_qux_quux_quuz_corge_grault_garply_waldo_fred_plugh_xyzzy.private",
124        );
125        assert!(struct_.is_err());
126
127        Ok(())
128    }
129
130    #[test]
131    fn test_display() -> Result<()> {
132        assert_eq!(FinalizeType::<CurrentNetwork>::from_str("field.public")?.to_string(), "field.public");
133        assert_eq!(FinalizeType::<CurrentNetwork>::from_str("signature.public")?.to_string(), "signature.public");
134        assert_eq!(
135            FinalizeType::<CurrentNetwork>::from_str("credits.aleo/mint_public.future")?.to_string(),
136            "credits.aleo/mint_public.future"
137        );
138
139        Ok(())
140    }
141}