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 }