Skip to main content

snarkvm_console_program/data_types/record_type/entry_type/
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 EntryType<N> {
19    /// Parses a string into the entry type.
20    #[inline]
21    fn parse(string: &str) -> ParserResult<Self> {
22        // Parse the mode from the string.
23        alt((
24            map(pair(PlaintextType::parse, tag(".constant")), |(plaintext_type, _)| Self::Constant(plaintext_type)),
25            map(pair(PlaintextType::parse, tag(".public")), |(plaintext_type, _)| Self::Public(plaintext_type)),
26            map(pair(PlaintextType::parse, tag(".private")), |(plaintext_type, _)| Self::Private(plaintext_type)),
27        ))(string)
28    }
29}
30
31impl<N: Network> FromStr for EntryType<N> {
32    type Err = Error;
33
34    /// Returns the entry type from a string literal.
35    fn from_str(string: &str) -> Result<Self> {
36        match Self::parse(string) {
37            Ok((remainder, object)) => {
38                // Ensure the remainder is empty.
39                ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
40                // Return the object.
41                Ok(object)
42            }
43            Err(error) => bail!("Failed to parse string. {error}"),
44        }
45    }
46}
47
48impl<N: Network> Debug for EntryType<N> {
49    /// Prints the entry type as a string.
50    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
51        Display::fmt(self, f)
52    }
53}
54
55impl<N: Network> Display for EntryType<N> {
56    /// Prints the entry type as a string.
57    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
58        match self {
59            Self::Constant(plaintext_type) => write!(f, "{plaintext_type}.constant"),
60            Self::Public(plaintext_type) => write!(f, "{plaintext_type}.public"),
61            Self::Private(plaintext_type) => write!(f, "{plaintext_type}.private"),
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(("", EntryType::<CurrentNetwork>::from_str("field.constant")?)),
78            EntryType::<CurrentNetwork>::parse("field.constant")
79        );
80        assert_eq!(
81            Ok(("", EntryType::<CurrentNetwork>::from_str("field.public")?)),
82            EntryType::<CurrentNetwork>::parse("field.public")
83        );
84        assert_eq!(
85            Ok(("", EntryType::<CurrentNetwork>::from_str("field.private")?)),
86            EntryType::<CurrentNetwork>::parse("field.private")
87        );
88
89        // Struct type.
90        assert_eq!(
91            Ok(("", EntryType::<CurrentNetwork>::from_str("signature.constant")?)),
92            EntryType::<CurrentNetwork>::parse("signature.constant")
93        );
94        assert_eq!(
95            Ok(("", EntryType::<CurrentNetwork>::from_str("signature.public")?)),
96            EntryType::<CurrentNetwork>::parse("signature.public")
97        );
98        assert_eq!(
99            Ok(("", EntryType::<CurrentNetwork>::from_str("signature.private")?)),
100            EntryType::<CurrentNetwork>::parse("signature.private")
101        );
102
103        Ok(())
104    }
105
106    #[test]
107    fn test_parse_fails() -> Result<()> {
108        // Literal type must contain visibility.
109        assert!(EntryType::<CurrentNetwork>::parse("field").is_err());
110        // Struct type must contain visibility.
111        assert!(EntryType::<CurrentNetwork>::parse("signature").is_err());
112        // Record type must contain record keyword.
113        assert!(EntryType::<CurrentNetwork>::parse("token").is_err());
114
115        // Must be non-empty.
116        assert!(EntryType::<CurrentNetwork>::parse("").is_err());
117
118        // Invalid characters.
119        assert!(EntryType::<CurrentNetwork>::parse("{}").is_err());
120        assert!(EntryType::<CurrentNetwork>::parse("_").is_err());
121        assert!(EntryType::<CurrentNetwork>::parse("__").is_err());
122        assert!(EntryType::<CurrentNetwork>::parse("___").is_err());
123        assert!(EntryType::<CurrentNetwork>::parse("-").is_err());
124        assert!(EntryType::<CurrentNetwork>::parse("--").is_err());
125        assert!(EntryType::<CurrentNetwork>::parse("---").is_err());
126        assert!(EntryType::<CurrentNetwork>::parse("*").is_err());
127        assert!(EntryType::<CurrentNetwork>::parse("**").is_err());
128        assert!(EntryType::<CurrentNetwork>::parse("***").is_err());
129
130        // Must not start with a number.
131        assert!(EntryType::<CurrentNetwork>::parse("1").is_err());
132        assert!(EntryType::<CurrentNetwork>::parse("2").is_err());
133        assert!(EntryType::<CurrentNetwork>::parse("3").is_err());
134        assert!(EntryType::<CurrentNetwork>::parse("1foo").is_err());
135        assert!(EntryType::<CurrentNetwork>::parse("12").is_err());
136        assert!(EntryType::<CurrentNetwork>::parse("111").is_err());
137
138        // Must fit within the data capacity of a base field element.
139        let struct_ = EntryType::<CurrentNetwork>::parse(
140            "foo_bar_baz_qux_quux_quuz_corge_grault_garply_waldo_fred_plugh_xyzzy.private",
141        );
142        assert!(struct_.is_err());
143
144        Ok(())
145    }
146
147    #[test]
148    fn test_display() -> Result<()> {
149        assert_eq!(EntryType::<CurrentNetwork>::from_str("field.constant")?.to_string(), "field.constant");
150        assert_eq!(EntryType::<CurrentNetwork>::from_str("field.public")?.to_string(), "field.public");
151        assert_eq!(EntryType::<CurrentNetwork>::from_str("field.private")?.to_string(), "field.private");
152
153        assert_eq!(EntryType::<CurrentNetwork>::from_str("signature.constant")?.to_string(), "signature.constant");
154        assert_eq!(EntryType::<CurrentNetwork>::from_str("signature.public")?.to_string(), "signature.public");
155        assert_eq!(EntryType::<CurrentNetwork>::from_str("signature.private")?.to_string(), "signature.private");
156
157        Ok(())
158    }
159}