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