snarkvm_console_program/id/
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 ProgramID<N> {
19    /// Parses a string into a program ID of the form `{name}.{network}`.
20    #[inline]
21    fn parse(string: &str) -> ParserResult<Self> {
22        // Parse the name, ".", and network-level domain (NLD) from the string.
23        map_res(pair(Identifier::parse, pair(tag("."), Identifier::parse)), |(name, (_, network))| {
24            // Return the program ID.
25            Self::try_from((name, network))
26        })(string)
27    }
28}
29
30impl<N: Network> FromStr for ProgramID<N> {
31    type Err = Error;
32
33    /// Parses a string into a program ID.
34    #[inline]
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 ProgramID<N> {
49    /// Prints the program ID 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 ProgramID<N> {
56    /// Prints the program ID as a string.
57    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
58        write!(f, "{name}.{network}", name = self.name, network = self.network)
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use snarkvm_console_network::MainnetV0;
66
67    type CurrentNetwork = MainnetV0;
68
69    #[test]
70    fn test_parse() -> Result<()> {
71        let id = ProgramID::<CurrentNetwork>::parse("bar.aleo").unwrap().1;
72        assert_eq!(id.name(), &Identifier::<CurrentNetwork>::from_str("bar")?);
73        assert_eq!(id.network(), &Identifier::<CurrentNetwork>::from_str("aleo")?);
74
75        assert!(ProgramID::<CurrentNetwork>::parse("foo").is_err());
76
77        Ok(())
78    }
79
80    #[test]
81    fn test_display() -> Result<()> {
82        let id = ProgramID::<CurrentNetwork>::from_str("bar.aleo")?;
83        assert_eq!("bar.aleo", id.to_string());
84
85        assert!(ProgramID::<CurrentNetwork>::from_str("foo").is_err());
86        assert!(ProgramID::<CurrentNetwork>::from_str("Bar.aleo").is_err());
87        assert!(ProgramID::<CurrentNetwork>::from_str("foO.aleo").is_err());
88        assert!(ProgramID::<CurrentNetwork>::from_str("0foo.aleo").is_err());
89        assert!(ProgramID::<CurrentNetwork>::from_str("0_foo.aleo").is_err());
90        assert!(ProgramID::<CurrentNetwork>::from_str("_foo.aleo").is_err());
91
92        Ok(())
93    }
94}