melodium_lang/
path.rs

1//! Provides script paths management.
2
3use melodium_common::descriptor::{Identifier, IdentifierRequirement, Version};
4
5/// Container-helper structure for paths in scripts.
6///
7/// It is used for handling `use` paths, as well as representing paths up to elements to build identifiers.
8#[derive(Clone, PartialEq, Debug)]
9pub struct Path {
10    /// Version of the elements located at path
11    version: Version,
12    /// Vector of string containing literally the path steps.
13    path: Vec<String>,
14}
15
16impl Path {
17    /// Instanciates a new path.
18    ///
19    /// ```
20    /// # use melodium_lang::Path;
21    /// # use melodium_common::descriptor::Version;
22    /// // use main/foo/bar::Element
23    /// let raw_valid_path = vec![  "main".to_string(),
24    ///                             "foo".to_string(),
25    ///                             "bar".to_string()];
26    ///
27    /// let valid_path = Path::new(Version::parse("0.1.0").unwrap(), raw_valid_path);
28    /// assert_eq!(valid_path.root(), "main");
29    /// assert!(valid_path.is_valid());
30    /// ```
31    pub fn new(version: Version, path: Vec<String>) -> Self {
32        Self { version, path }
33    }
34
35    /// Version used for the path.
36    pub fn version(&self) -> &Version {
37        &self.version
38    }
39
40    /// Gives immutable reference to vector of string containing literally the path steps.
41    pub fn path(&self) -> &Vec<String> {
42        &self.path
43    }
44
45    pub fn root(&self) -> String {
46        self.path.first().map(|s| s.clone()).unwrap_or_default()
47    }
48
49    /// Tells if the path is valid.
50    ///
51    /// Currently check if at least a root is set up and no empty elements are present
52    pub fn is_valid(&self) -> bool {
53        if self.path.len() > 0 {
54            !self.path.iter().any(|s| s.is_empty())
55        } else {
56            false
57        }
58    }
59
60    /// Turn the path into an identifier.
61    ///
62    /// * `element_name`: name of the element supposed to be identified under that path.
63    ///
64    /// # Warning
65    /// Return `None` if the path is invalid.
66    pub fn to_identifier(&self, element_name: &str) -> Option<Identifier> {
67        if self.is_valid() {
68            Some(Identifier::new_versionned(
69                &self.version,
70                self.path.clone(),
71                element_name,
72            ))
73        } else {
74            None
75        }
76    }
77
78    pub fn to_identifier_requirement(&self, element_name: &str) -> Option<IdentifierRequirement> {
79        if self.is_valid() {
80            Some(
81                (&Identifier::new_versionned(&self.version, self.path.clone(), element_name))
82                    .into(),
83            )
84        } else {
85            None
86        }
87    }
88}