From 7c5bec7db2a2fc8c796d5f31bdeb03da0946133d Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 19 Feb 2023 13:49:41 +0100 Subject: feat: add project & registry parsing /w commands --- src/xml/element.rs | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/xml/element.rs (limited to 'src/xml/element.rs') 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, +} + +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> From 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.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: &Name, child_elements: ChildElements) -> Self + where + Name: ToString, + ChildElements: Into, + { + 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; +} -- cgit v1.2.3-18-g5258