umya_spreadsheet/structs/
numbering_formats.rs1use 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}