chemp 0.9.6

chemical formulas parser
Documentation
use crate::tokens::{Component, Element};

#[derive(Debug, PartialEq)]
pub struct Group {
    composition: Vec<Component>,
    subscript: usize,
}

impl Group {
    pub(crate) fn new() -> Self {
        Self {
            composition: vec![],
            subscript: 1,
        }
    }

    #[allow(unused)]
    pub(crate) fn from(composition: Vec<Component>, subscript: usize) -> Self {
        Self {
            composition,
            subscript,
        }
    }

    pub(crate) fn add_component(&mut self, component: Component) {
        self.composition.push(component);
    }

    pub(crate) fn add_subscript(&mut self, subscript: usize) {
        self.subscript = subscript;
    }

    pub(crate) fn elements(&self) -> Vec<Element> {
        let mut elements = vec![];

        self.composition
            .iter()
            .for_each(|component| match component {
                Component::Element(element) => {
                    elements.push(Element::multiply(element, self.subscript));
                }

                Component::Group(group) => {
                    group.elements().iter().for_each(|element| {
                        elements.push(Element::multiply(element, self.subscript));
                    });
                }
            });

        elements
    }
}

#[cfg(test)]
mod tests {
    use crate::tokens::{Component, Element, Group};

    #[test]
    fn subscript_multiplication() {
        let group = Group::from(
            vec![
                Component::Element(Element::from("N", 1)),
                Component::Element(Element::from("O", 3)),
            ],
            2,
        );

        assert_eq!(
            group.elements(),
            vec![Element::from("N", 2), Element::from("O", 6)]
        );
    }

    #[test]
    fn nested_group() {
        let group = Group::from(
            vec![
                Component::Element(Element::from("N", 1)),
                Component::Group(Group::from(
                    vec![Component::Element(Element::from("H", 2))],
                    2,
                )),
            ],
            2,
        );

        assert_eq!(
            group.elements(),
            vec![Element::from("N", 2), Element::from("H", 8)]
        );
    }
}