/ console / program / src / locator / parse.rs
parse.rs
 1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
 2  // This file is part of the alphavm 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  
16  use super::*;
17  
18  impl<N: Network> Parser for Locator<N> {
19      /// Parses a string into a locator of the form `{program_id}/{resource}`.
20      #[inline]
21      fn parse(string: &str) -> ParserResult<Self> {
22          // Parse the program ID from the string.
23          let (string, id) = ProgramID::parse(string)?;
24          // Parse the "/" and resource from the string.
25          let (string, (_, resource)) = pair(tag("/"), Identifier::parse)(string)?;
26          // Return the locator.
27          Ok((string, Self { id, resource }))
28      }
29  }
30  
31  impl<N: Network> FromStr for Locator<N> {
32      type Err = Error;
33  
34      /// Parses a string into a locator.
35      #[inline]
36      fn from_str(string: &str) -> Result<Self> {
37          match Self::parse(string) {
38              Ok((remainder, object)) => {
39                  // Ensure the remainder is empty.
40                  ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
41                  // Return the object.
42                  Ok(object)
43              }
44              Err(error) => bail!("Failed to parse string. {error}"),
45          }
46      }
47  }
48  
49  impl<N: Network> Debug for Locator<N> {
50      /// Prints the locator as a string.
51      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
52          Display::fmt(self, f)
53      }
54  }
55  
56  impl<N: Network> Display for Locator<N> {
57      /// Prints the locator as a string.
58      fn fmt(&self, f: &mut Formatter) -> fmt::Result {
59          write!(f, "{id}/{resource}", id = self.id, resource = self.resource)
60      }
61  }
62  
63  #[cfg(test)]
64  mod tests {
65      use super::*;
66      use alphavm_console_network::MainnetV0;
67  
68      type CurrentNetwork = MainnetV0;
69  
70      #[test]
71      fn test_import_parse() -> Result<()> {
72          let locator = Locator::<CurrentNetwork>::parse("foo.alpha/compute").unwrap().1;
73          assert_eq!(locator.name(), &Identifier::<CurrentNetwork>::from_str("foo")?);
74          assert_eq!(locator.network(), &Identifier::<CurrentNetwork>::from_str("alpha")?);
75          assert_eq!(locator.resource(), &Identifier::<CurrentNetwork>::from_str("compute")?);
76  
77          assert!(Locator::<CurrentNetwork>::parse("foo.alpha").is_err());
78          assert!(Locator::<CurrentNetwork>::parse("foo/compute").is_err());
79  
80          Ok(())
81      }
82  
83      #[test]
84      fn test_import_display() -> Result<()> {
85          let id = Locator::<CurrentNetwork>::from_str("foo.alpha/compute")?;
86          assert_eq!("foo.alpha/compute", id.to_string());
87  
88          assert!(Locator::<CurrentNetwork>::parse("foo.alpha").is_err());
89          assert!(Locator::<CurrentNetwork>::parse("foo/compute").is_err());
90  
91          Ok(())
92      }
93  }