Skip to main content

umya_spreadsheet/structs/
fill.rs

1use std::io::Cursor;
2
3use md5::Digest;
4use quick_xml::{
5    Reader,
6    Writer,
7    events::{
8        BytesStart,
9        Event,
10    },
11};
12
13use super::{
14    GradientFill,
15    PatternFill,
16    PatternValues,
17};
18use crate::{
19    reader::driver::xml_read_loop,
20    writer::driver::{
21        write_end_tag,
22        write_start_tag,
23    },
24};
25
26#[derive(Default, Debug, Clone, PartialEq, PartialOrd)]
27pub struct Fill {
28    pattern_fill:  Option<Box<PatternFill>>,
29    gradient_fill: Option<Box<GradientFill>>,
30}
31
32impl Fill {
33    #[inline]
34    #[must_use]
35    pub fn pattern_fill(&self) -> Option<&PatternFill> {
36        self.pattern_fill.as_deref()
37    }
38
39    #[inline]
40    #[must_use]
41    #[deprecated(since = "3.0.0", note = "Use pattern_fill()")]
42    pub fn get_pattern_fill(&self) -> Option<&PatternFill> {
43        self.pattern_fill()
44    }
45
46    #[inline]
47    #[allow(clippy::unnecessary_unwrap)]
48    pub fn pattern_fill_mut(&mut self) -> &mut PatternFill {
49        if self.pattern_fill.is_some() {
50            return self.pattern_fill.as_mut().unwrap();
51        }
52        self.set_pattern_fill(PatternFill::default());
53        self.pattern_fill.as_mut().unwrap()
54    }
55
56    #[inline]
57    #[deprecated(since = "3.0.0", note = "Use pattern_fill_mut()")]
58    pub fn get_pattern_fill_mut(&mut self) -> &mut PatternFill {
59        self.pattern_fill_mut()
60    }
61
62    #[inline]
63    pub fn set_pattern_fill(&mut self, value: PatternFill) -> &mut Self {
64        self.pattern_fill = Some(Box::new(value));
65        self.gradient_fill = None;
66        self
67    }
68
69    #[inline]
70    #[must_use]
71    pub fn gradient_fill(&self) -> Option<&GradientFill> {
72        self.gradient_fill.as_deref()
73    }
74
75    #[inline]
76    #[must_use]
77    #[deprecated(since = "3.0.0", note = "Use gradient_fill()")]
78    pub fn get_gradient_fill(&self) -> Option<&GradientFill> {
79        self.gradient_fill()
80    }
81
82    #[inline]
83    #[allow(clippy::unnecessary_unwrap)]
84    pub fn gradient_fill_mut(&mut self) -> &mut GradientFill {
85        if self.gradient_fill.is_some() {
86            return self.gradient_fill.as_mut().unwrap();
87        }
88        self.set_gradient_fill(GradientFill::default());
89        self.gradient_fill.as_mut().unwrap()
90    }
91
92    #[inline]
93    #[deprecated(since = "3.0.0", note = "Use gradient_fill_mut()")]
94    pub fn get_gradient_fill_mut(&mut self) -> &mut GradientFill {
95        self.gradient_fill_mut()
96    }
97
98    #[inline]
99    pub fn set_gradient_fill(&mut self, value: GradientFill) -> &mut Self {
100        self.pattern_fill = None;
101        self.gradient_fill = Some(Box::new(value));
102        self
103    }
104
105    #[inline]
106    pub(crate) fn default_value() -> Self {
107        let mut def = Self::default();
108        let mut pfill = PatternFill::default();
109        pfill.set_pattern_type(PatternValues::None);
110        def.set_pattern_fill(pfill);
111        def
112    }
113
114    #[inline]
115    #[deprecated(since = "3.0.0", note = "Use default_value()")]
116    pub(crate) fn get_default_value() -> Self {
117        let mut def = Self::default();
118        let mut pfill = PatternFill::default();
119        pfill.set_pattern_type(PatternValues::None);
120        def.set_pattern_fill(pfill);
121        def
122    }
123
124    #[inline]
125    pub(crate) fn default_value_2() -> Self {
126        let mut def = Self::default();
127        let mut pfill = PatternFill::default();
128        pfill.set_pattern_type(PatternValues::Gray125);
129        def.set_pattern_fill(pfill);
130        def
131    }
132
133    #[inline]
134    #[deprecated(since = "3.0.0", note = "Use default_value_2()")]
135    pub(crate) fn get_default_value_2() -> Self {
136        let mut def = Self::default();
137        let mut pfill = PatternFill::default();
138        pfill.set_pattern_type(PatternValues::Gray125);
139        def.set_pattern_fill(pfill);
140        def
141    }
142
143    pub(crate) fn hash_code(&self) -> String {
144        format!(
145            "{:x}",
146            md5::Md5::digest(format!(
147                "{}{}",
148                match &self.pattern_fill {
149                    Some(v) => {
150                        v.hash_code()
151                    }
152                    None => {
153                        "NONE".to_string()
154                    }
155                },
156                match &self.gradient_fill {
157                    Some(v) => {
158                        v.hash_code()
159                    }
160                    None => {
161                        "NONE".to_string()
162                    }
163                },
164            ))
165        )
166    }
167
168    #[deprecated(since = "3.0.0", note = "Use hash_code()")]
169    pub(crate) fn get_hash_code(&self) -> String {
170        self.hash_code()
171    }
172
173    // When opened in software such as Excel, it is visually blank.
174    #[inline]
175    pub(crate) fn is_visually_empty(&self) -> bool {
176        !(self
177            .pattern_fill
178            .as_ref()
179            .is_some_and(|x| !x.is_visually_empty())
180            || self.gradient_fill.as_ref().is_some())
181    }
182
183    pub(crate) fn set_attributes<R: std::io::BufRead>(
184        &mut self,
185        reader: &mut Reader<R>,
186        _e: &BytesStart,
187    ) {
188        xml_read_loop!(
189            reader,
190            Event::Empty(ref e) => {
191                if e.name().into_inner() == b"patternFill" {
192                    let mut obj = PatternFill::default();
193                    obj.set_attributes(reader, e, true);
194                    self.set_pattern_fill(obj);
195                }
196            },
197            Event::Start(ref e) => {
198                match e.name().into_inner() {
199                    b"patternFill" => {
200                        let mut obj = PatternFill::default();
201                        obj.set_attributes(reader, e, false);
202                        self.set_pattern_fill(obj);
203                    }
204                    b"gradientFill" => {
205                        let mut obj = GradientFill::default();
206                        obj.set_attributes(reader, e);
207                        self.set_gradient_fill(obj);
208                    }
209                    _ => (),
210                }
211            },
212            Event::End(ref e) => {
213                if e.name().into_inner() == b"fill" {
214                    return
215                }
216            },
217            Event::Eof => panic!("Error: Could not find {} end element", "fill")
218        );
219    }
220
221    pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
222        // fill
223        write_start_tag(writer, "fill", vec![], false);
224
225        // gradientFill
226        if let Some(v) = &self.pattern_fill {
227            v.write_to(writer);
228        }
229
230        // patternFill
231        if let Some(v) = &self.gradient_fill {
232            v.write_to(writer);
233        }
234
235        write_end_tag(writer, "fill");
236    }
237}