umya_spreadsheet/structs/
numbering_formats.rs

1// numFmts
2use super::NumberingFormat;
3use super::Style;
4use crate::reader::driver::*;
5use crate::writer::driver::*;
6use quick_xml::events::{BytesStart, Event};
7use quick_xml::Reader;
8use quick_xml::Writer;
9use std::collections::HashMap;
10use std::io::Cursor;
11
12#[derive(Clone, Default, Debug)]
13pub(crate) struct NumberingFormats {
14    numbering_format: HashMap<u32, NumberingFormat>,
15}
16
17impl NumberingFormats {
18    #[inline]
19    pub(crate) fn get_numbering_format(&self) -> &HashMap<u32, NumberingFormat> {
20        &self.numbering_format
21    }
22
23    #[inline]
24    pub(crate) fn _get_numbering_format_mut(&mut self) -> &mut HashMap<u32, NumberingFormat> {
25        &mut self.numbering_format
26    }
27
28    #[inline]
29    pub(crate) fn set_numbering_format(&mut self, value: NumberingFormat) -> &mut Self {
30        let number_format_id = value.get_number_format_id();
31        self.numbering_format.insert(*number_format_id, value);
32        self
33    }
34
35    #[inline]
36    pub(crate) fn _init_setup(&mut self) -> &mut Self {
37        self.get_build_in_formats();
38        self
39    }
40
41    pub(crate) fn get_build_in_formats(&mut self) {
42        for (index, code) in super::numbering_format::FILL_BUILT_IN_FORMAT_CODES.iter() {
43            let mut obj = NumberingFormat::default();
44            obj.set_number_format_id_crate(*index)
45                .set_format_code_crate(code.clone());
46            self.set_numbering_format(obj);
47        }
48    }
49
50    pub(crate) fn set_style(&mut self, style: &Style) -> u32 {
51        match style.get_numbering_format() {
52            Some(v) => {
53                if *v.get_is_build_in() {
54                    return *v.get_number_format_id();
55                }
56
57                let hash_code = v.get_hash_code();
58
59                let mut id = 175;
60                for (index, numbering_format) in &self.numbering_format {
61                    if numbering_format.get_hash_code() == hash_code {
62                        return *index;
63                    }
64                    if &id < index {
65                        id = *index;
66                    }
67                }
68                id += 1;
69                let mut num = v.clone();
70                num.set_number_format_id_crate(id);
71                self.set_numbering_format(num);
72                id
73            }
74            None => 0,
75        }
76    }
77
78    pub(crate) fn set_attributes<R: std::io::BufRead>(
79        &mut self,
80        reader: &mut Reader<R>,
81        _e: &BytesStart,
82    ) {
83        xml_read_loop!(
84            reader,
85            Event::Empty(ref e) => {
86                if e.name().into_inner() == b"numFmt" {
87                    let mut obj = NumberingFormat::default();
88                    obj.set_attributes(reader, e);
89                    self.set_numbering_format(obj);
90                }
91            },
92            Event::End(ref e) => {
93                if e.name().into_inner() == b"numFmts" {
94                    return
95                }
96            },
97            Event::Eof => panic!("Error: Could not find {} end element", "numFmts")
98        );
99    }
100
101    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
102        let formats_to_write: HashMap<_, _> = self
103            .numbering_format
104            .iter()
105            .filter(|(k, v)| !*v.get_is_build_in())
106            .collect();
107        if formats_to_write.is_empty() {
108            return;
109        }
110
111        let cnt = formats_to_write.len();
112        let cnt_str = cnt.to_string();
113        write_start_tag(writer, "numFmts", vec![("count", &cnt_str)], false);
114
115        formats_to_write
116            .into_iter()
117            .enumerate()
118            .for_each(|(_, (index, numbering_format))| {
119                numbering_format.write_to(writer, index);
120            });
121
122        write_end_tag(writer, "numFmts");
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129
130    #[test]
131    fn set_style() {
132        let mut obj = NumberingFormats::default();
133
134        let mut style = Style::default();
135        style
136            .get_number_format_mut()
137            .set_format_code(NumberingFormat::FORMAT_TEXT);
138        assert_eq!(obj.set_style(&style), 49);
139
140        let mut style = Style::default();
141        style
142            .get_number_format_mut()
143            .set_format_code("test-yyyy-mm-dd");
144        assert_eq!(obj.set_style(&style), 176);
145
146        let mut style = Style::default();
147        style
148            .get_number_format_mut()
149            .set_format_code("test-yyyy/mm/dd");
150        assert_eq!(obj.set_style(&style), 177);
151
152        let mut style = Style::default();
153        style
154            .get_number_format_mut()
155            .set_format_code("test-yyyy-mm-dd");
156        assert_eq!(obj.set_style(&style), 176);
157
158        let mut style = Style::default();
159        style.get_number_format_mut().set_format_code("m/d/yy");
160        assert_eq!(obj.set_style(&style), 30);
161
162        let mut style = Style::default();
163        style
164            .get_number_format_mut()
165            .set_format_code(NumberingFormat::FORMAT_TEXT);
166        assert_eq!(obj.set_style(&style), 49);
167
168        let mut style = Style::default();
169        style
170            .get_number_format_mut()
171            .set_format_code(NumberingFormat::FORMAT_DATE_TIME5);
172        assert_eq!(obj.set_style(&style), 45);
173    }
174}