umya-spreadsheet 2.3.3

umya-spreadsheet is a library written in pure Rust to read and write xlsx file.
Documentation
// numFmts
use super::NumberingFormat;
use super::Style;
use crate::reader::driver::*;
use crate::writer::driver::*;
use quick_xml::events::{BytesStart, Event};
use quick_xml::Reader;
use quick_xml::Writer;
use std::collections::HashMap;
use std::io::Cursor;

#[derive(Clone, Default, Debug)]
pub(crate) struct NumberingFormats {
    numbering_format: HashMap<u32, NumberingFormat>,
}

impl NumberingFormats {
    #[inline]
    pub(crate) fn get_numbering_format(&self) -> &HashMap<u32, NumberingFormat> {
        &self.numbering_format
    }

    #[inline]
    pub(crate) fn _get_numbering_format_mut(&mut self) -> &mut HashMap<u32, NumberingFormat> {
        &mut self.numbering_format
    }

    #[inline]
    pub(crate) fn set_numbering_format(&mut self, value: NumberingFormat) -> &mut Self {
        let number_format_id = value.get_number_format_id();
        self.numbering_format.insert(*number_format_id, value);
        self
    }

    #[inline]
    pub(crate) fn _init_setup(&mut self) -> &mut Self {
        self.get_build_in_formats();
        self
    }

    pub(crate) fn get_build_in_formats(&mut self) {
        for (index, code) in super::numbering_format::FILL_BUILT_IN_FORMAT_CODES.iter() {
            let mut obj = NumberingFormat::default();
            obj.set_number_format_id_crate(*index)
                .set_format_code_crate(code.clone());
            self.set_numbering_format(obj);
        }
    }

    pub(crate) fn set_style(&mut self, style: &Style) -> u32 {
        match style.get_numbering_format() {
            Some(v) => {
                if *v.get_is_build_in() {
                    return *v.get_number_format_id();
                }

                let hash_code = v.get_hash_code();

                let mut id = 175;
                for (index, numbering_format) in &self.numbering_format {
                    if numbering_format.get_hash_code() == hash_code {
                        return *index;
                    }
                    if &id < index {
                        id = *index;
                    }
                }
                id += 1;
                let mut num = v.clone();
                num.set_number_format_id_crate(id);
                self.set_numbering_format(num);
                id
            }
            None => 0,
        }
    }

    pub(crate) fn set_attributes<R: std::io::BufRead>(
        &mut self,
        reader: &mut Reader<R>,
        _e: &BytesStart,
    ) {
        xml_read_loop!(
            reader,
            Event::Empty(ref e) => {
                if e.name().into_inner() == b"numFmt" {
                    let mut obj = NumberingFormat::default();
                    obj.set_attributes(reader, e);
                    self.set_numbering_format(obj);
                }
            },
            Event::End(ref e) => {
                if e.name().into_inner() == b"numFmts" {
                    return
                }
            },
            Event::Eof => panic!("Error: Could not find {} end element", "numFmts")
        );
    }

    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
        let formats_to_write: HashMap<_, _> = self
            .numbering_format
            .iter()
            .filter(|(k, v)| !*v.get_is_build_in())
            .collect();
        if formats_to_write.is_empty() {
            return;
        }

        let cnt = formats_to_write.len();
        let cnt_str = cnt.to_string();
        write_start_tag(writer, "numFmts", vec![("count", &cnt_str)], false);

        formats_to_write
            .into_iter()
            .enumerate()
            .for_each(|(_, (index, numbering_format))| {
                numbering_format.write_to(writer, index);
            });

        write_end_tag(writer, "numFmts");
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn set_style() {
        let mut obj = NumberingFormats::default();

        let mut style = Style::default();
        style
            .get_number_format_mut()
            .set_format_code(NumberingFormat::FORMAT_TEXT);
        assert_eq!(obj.set_style(&style), 49);

        let mut style = Style::default();
        style
            .get_number_format_mut()
            .set_format_code("test-yyyy-mm-dd");
        assert_eq!(obj.set_style(&style), 176);

        let mut style = Style::default();
        style
            .get_number_format_mut()
            .set_format_code("test-yyyy/mm/dd");
        assert_eq!(obj.set_style(&style), 177);

        let mut style = Style::default();
        style
            .get_number_format_mut()
            .set_format_code("test-yyyy-mm-dd");
        assert_eq!(obj.set_style(&style), 176);

        let mut style = Style::default();
        style.get_number_format_mut().set_format_code("m/d/yy");
        assert_eq!(obj.set_style(&style), 30);

        let mut style = Style::default();
        style
            .get_number_format_mut()
            .set_format_code(NumberingFormat::FORMAT_TEXT);
        assert_eq!(obj.set_style(&style), 49);

        let mut style = Style::default();
        style
            .get_number_format_mut()
            .set_format_code(NumberingFormat::FORMAT_DATE_TIME5);
        assert_eq!(obj.set_style(&style), 45);
    }
}