From 11c39d50411a747eedac4c6a16fedf598ae798f5 Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 23 Feb 2023 22:35:06 +0100 Subject: feat: add project & getting function entries --- src/xml/element.rs | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 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..647fe90 --- /dev/null +++ b/src/xml/element.rs @@ -0,0 +1,186 @@ +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Elements +{ + elements: Vec, +} + +impl Elements +{ + pub fn get_first_tagged(&self) -> Option<&Tagged> + { + self.elements.iter().find_map(|element| match element { + Element::Tagged(tagged_element) => Some(tagged_element), + _ => None, + }) + } + + pub fn get_first_tagged_with_name(&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_first_tagged_with_name_and_attr( + &self, + tag_name: &str, + attribute: &Attribute, + ) -> Option<&Tagged> + { + self.elements.iter().find_map(|element| match element { + Element::Tagged(tagged_element) + if tagged_element.name == tag_name + && tagged_element + .attributes + .iter() + .any(|attr| attr == attribute) => + { + 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, Clone)] +pub enum Element +{ + Tagged(Tagged), + Text(String), + Comment(String), +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Tagged +{ + name: String, + child_elements: Elements, + attributes: Vec, +} + +impl Tagged +{ + pub fn new( + name: &Name, + child_elements: ChildElements, + attributes: Attrs, + ) -> Self + where + Name: ToString, + ChildElements: Into, + Attrs: IntoIterator, + { + Self { + name: name.to_string(), + child_elements: child_elements.into(), + attributes: attributes.into_iter().collect(), + } + } + + pub fn name(&self) -> &str + { + &self.name + } + + pub fn child_elements(&self) -> &Elements + { + &self.child_elements + } +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct Attribute +{ + pub key: String, + pub value: Vec, +} + +pub trait FromElements: Sized +{ + type Error; + + fn from_elements(elements: &Elements) -> Result; +} -- cgit v1.2.3-18-g5258