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}