Skip to main content

umya_spreadsheet/structs/
fill.rs

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