diff options
author | HampusM <hampus@hampusmat.com> | 2023-02-19 13:49:41 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-02-19 18:27:23 +0100 |
commit | 7c5bec7db2a2fc8c796d5f31bdeb03da0946133d (patch) | |
tree | 7c80fa13c3aae658e63d9d6ae553593ebd7a93be /src/xml/element.rs | |
parent | 46c316bd9665cdc6026ccd2a4119e4c46778b65b (diff) |
feat: add project & registry parsing /w commands
Diffstat (limited to 'src/xml/element.rs')
-rw-r--r-- | src/xml/element.rs | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/xml/element.rs b/src/xml/element.rs new file mode 100644 index 0000000..f469480 --- /dev/null +++ b/src/xml/element.rs @@ -0,0 +1,144 @@ +#[derive(Debug, PartialEq, Eq)] +pub struct Elements +{ + elements: Vec<Element>, +} + +impl Elements +{ + pub fn get_first_tagged_element(&self, tag_name: &str) -> Option<&Tagged> + { + self.elements.iter().find_map(|element| match element { + Element::Tagged(tagged_element) if tagged_element.name == tag_name => { + Some(tagged_element) + } + _ => None, + }) + } + + pub fn get_all_tagged_elements_with_name(&self, tag_name: &str) -> Vec<&Tagged> + { + self.elements + .iter() + .filter_map(|element| match element { + Element::Tagged(tagged_element) if tagged_element.name == tag_name => { + Some(tagged_element) + } + _ => None, + }) + .collect() + } + + pub fn get_first_text_element(&self) -> Option<&String> + { + self.elements.iter().find_map(|element| match element { + Element::Text(text) => Some(text), + _ => None, + }) + } + + pub fn get_all_text_elements(&self) -> Vec<&String> + { + self.elements + .iter() + .filter_map(|element| match element { + Element::Text(text) => Some(text), + _ => None, + }) + .collect() + } + + pub fn has_tagged_element(&self, tag_name: &str) -> bool + { + self.elements.iter().any(|element| { + matches!( + element, + Element::Tagged(tagged_element) if tagged_element.name == tag_name + ) + }) + } +} + +impl<IntoIter: IntoIterator<Item = Element>> From<IntoIter> for Elements +{ + fn from(into_iter: IntoIter) -> Self + { + Self { + elements: into_iter.into_iter().collect(), + } + } +} + +impl<'elements> IntoIterator for &'elements Elements +{ + type IntoIter = Iter<'elements>; + type Item = &'elements Element; + + fn into_iter(self) -> Self::IntoIter + { + Self::IntoIter { + elements: self.elements.iter(), + } + } +} + +pub struct Iter<'elements> +{ + elements: std::slice::Iter<'elements, Element>, +} + +impl<'elements> Iterator for Iter<'elements> +{ + type Item = &'elements Element; + + fn next(&mut self) -> Option<Self::Item> + { + self.elements.next() + } +} + +#[derive(Debug, PartialEq, Eq)] +pub enum Element +{ + Tagged(Tagged), + Text(String), + Comment(String), +} + +#[derive(Debug, PartialEq, Eq)] +pub struct Tagged +{ + name: String, + child_elements: Elements, +} + +impl Tagged +{ + pub fn new<Name, ChildElements>(name: &Name, child_elements: ChildElements) -> Self + where + Name: ToString, + ChildElements: Into<Elements>, + { + Self { + name: name.to_string(), + child_elements: child_elements.into(), + } + } + + pub fn name(&self) -> &str + { + &self.name + } + + pub fn child_elements(&self) -> &Elements + { + &self.child_elements + } +} + +pub trait FromElements: Sized +{ + type Error; + + fn from_elements(elements: &Elements) -> Result<Self, Self::Error>; +} |