Skip to main content

umya_spreadsheet/structs/
conditional_formatting_rule.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    BooleanValue,
14    ColorScale,
15    ConditionalFormatValues,
16    ConditionalFormattingOperatorValues,
17    DataBar,
18    DifferentialFormats,
19    EnumValue,
20    Formula,
21    IconSet,
22    Int32Value,
23    StringValue,
24    Style,
25    TimePeriodValues,
26    UInt32Value,
27};
28use crate::{
29    reader::driver::{
30        get_attribute,
31        set_string_from_xml,
32        xml_read_loop,
33    },
34    writer::driver::{
35        write_end_tag,
36        write_start_tag,
37    },
38};
39
40#[derive(Clone, Default, Debug)]
41pub struct ConditionalFormattingRule {
42    r#type:        EnumValue<ConditionalFormatValues>,
43    operator:      EnumValue<ConditionalFormattingOperatorValues>,
44    text:          StringValue,
45    priority:      Int32Value,
46    percent:       BooleanValue,
47    bottom:        BooleanValue,
48    rank:          UInt32Value,
49    stop_if_true:  BooleanValue,
50    std_dev:       Int32Value,
51    above_average: BooleanValue,
52    equal_average: BooleanValue,
53    time_period:   EnumValue<TimePeriodValues>,
54    style:         Option<Box<Style>>,
55    color_scale:   Option<ColorScale>,
56    data_bar:      Option<DataBar>,
57    icon_set:      Option<IconSet>,
58    formula:       Option<Box<Formula>>,
59}
60
61impl ConditionalFormattingRule {
62    #[inline]
63    #[must_use]
64    pub fn get_type(&self) -> &ConditionalFormatValues {
65        self.r#type.value()
66    }
67
68    #[inline]
69    pub fn set_type(&mut self, value: ConditionalFormatValues) -> &mut Self {
70        self.r#type.set_value(value);
71        self
72    }
73
74    #[inline]
75    #[must_use]
76    pub fn operator(&self) -> &ConditionalFormattingOperatorValues {
77        self.operator.value()
78    }
79
80    #[inline]
81    #[must_use]
82    #[deprecated(since = "3.0.0", note = "Use operator()")]
83    pub fn get_operator(&self) -> &ConditionalFormattingOperatorValues {
84        self.operator()
85    }
86
87    #[inline]
88    pub fn set_operator(&mut self, value: ConditionalFormattingOperatorValues) -> &mut Self {
89        self.operator.set_value(value);
90        self
91    }
92
93    #[inline]
94    #[must_use]
95    pub fn text(&self) -> &str {
96        self.text.value_str()
97    }
98
99    #[inline]
100    #[must_use]
101    #[deprecated(since = "3.0.0", note = "Use text()")]
102    pub fn get_text(&self) -> &str {
103        self.text()
104    }
105
106    #[inline]
107    pub fn set_text<S: Into<String>>(&mut self, value: S) -> &mut Self {
108        self.text.set_value(value.into());
109        self
110    }
111
112    #[inline]
113    #[must_use]
114    pub fn priority(&self) -> i32 {
115        self.priority.value()
116    }
117
118    #[inline]
119    #[must_use]
120    #[deprecated(since = "3.0.0", note = "Use priority()")]
121    pub fn get_priority(&self) -> i32 {
122        self.priority()
123    }
124
125    #[inline]
126    pub fn set_priority(&mut self, value: i32) -> &mut Self {
127        self.priority.set_value(value);
128        self
129    }
130
131    #[inline]
132    #[must_use]
133    pub fn percent(&self) -> bool {
134        self.percent.value()
135    }
136
137    #[inline]
138    #[must_use]
139    #[deprecated(since = "3.0.0", note = "Use percent()")]
140    pub fn get_percent(&self) -> bool {
141        self.percent()
142    }
143
144    #[inline]
145    pub fn set_percent(&mut self, value: bool) -> &mut Self {
146        self.percent.set_value(value);
147        self
148    }
149
150    #[inline]
151    #[must_use]
152    pub fn bottom(&self) -> bool {
153        self.bottom.value()
154    }
155
156    #[inline]
157    #[must_use]
158    #[deprecated(since = "3.0.0", note = "Use bottom()")]
159    pub fn get_bottom(&self) -> bool {
160        self.bottom()
161    }
162
163    #[inline]
164    pub fn set_bottom(&mut self, value: bool) -> &mut Self {
165        self.bottom.set_value(value);
166        self
167    }
168
169    #[inline]
170    #[must_use]
171    pub fn rank(&self) -> u32 {
172        self.rank.value()
173    }
174
175    #[inline]
176    #[must_use]
177    #[deprecated(since = "3.0.0", note = "Use rank()")]
178    pub fn get_rank(&self) -> u32 {
179        self.rank()
180    }
181
182    #[inline]
183    pub fn set_rank(&mut self, value: u32) -> &mut Self {
184        self.rank.set_value(value);
185        self
186    }
187
188    #[inline]
189    #[must_use]
190    pub fn stop_if_true(&self) -> bool {
191        self.stop_if_true.value()
192    }
193
194    #[inline]
195    #[must_use]
196    #[deprecated(since = "3.0.0", note = "Use stop_if_true()")]
197    pub fn get_stop_if_true(&self) -> bool {
198        self.stop_if_true()
199    }
200
201    #[inline]
202    pub fn set_stop_if_true(&mut self, value: bool) -> &mut Self {
203        self.stop_if_true.set_value(value);
204        self
205    }
206
207    #[inline]
208    #[must_use]
209    pub fn std_dev(&self) -> i32 {
210        self.std_dev.value()
211    }
212
213    #[inline]
214    #[must_use]
215    #[deprecated(since = "3.0.0", note = "Use std_dev()")]
216    pub fn get_std_dev(&self) -> i32 {
217        self.std_dev()
218    }
219
220    #[inline]
221    pub fn set_std_dev(&mut self, value: i32) -> &mut Self {
222        self.std_dev.set_value(value);
223        self
224    }
225
226    #[inline]
227    #[must_use]
228    pub fn above_average(&self) -> bool {
229        self.above_average.value()
230    }
231
232    #[inline]
233    #[must_use]
234    #[deprecated(since = "3.0.0", note = "Use above_average()")]
235    pub fn get_above_average(&self) -> bool {
236        self.above_average()
237    }
238
239    #[inline]
240    pub fn set_above_average(&mut self, value: bool) -> &mut Self {
241        self.above_average.set_value(value);
242        self
243    }
244
245    #[inline]
246    #[must_use]
247    pub fn equal_average(&self) -> bool {
248        self.equal_average.value()
249    }
250
251    #[inline]
252    #[must_use]
253    #[deprecated(since = "3.0.0", note = "Use equal_average()")]
254    pub fn get_equal_average(&self) -> bool {
255        self.equal_average()
256    }
257
258    #[inline]
259    pub fn set_equal_average(&mut self, value: bool) -> &mut Self {
260        self.equal_average.set_value(value);
261        self
262    }
263
264    #[inline]
265    #[must_use]
266    pub fn time_period(&self) -> &TimePeriodValues {
267        self.time_period.value()
268    }
269
270    #[inline]
271    #[must_use]
272    #[deprecated(since = "3.0.0", note = "Use time_period()")]
273    pub fn get_time_period(&self) -> &TimePeriodValues {
274        self.time_period()
275    }
276
277    #[inline]
278    pub fn set_time_period(&mut self, value: TimePeriodValues) -> &mut Self {
279        self.time_period.set_value(value);
280        self
281    }
282
283    #[inline]
284    #[must_use]
285    pub fn style(&self) -> Option<&Style> {
286        self.style.as_deref()
287    }
288
289    #[inline]
290    #[must_use]
291    #[deprecated(since = "3.0.0", note = "Use style()")]
292    pub fn get_style(&self) -> Option<&Style> {
293        self.style()
294    }
295
296    #[inline]
297    pub fn set_style(&mut self, value: Style) -> &mut Self {
298        self.style = Some(Box::new(value));
299        self
300    }
301
302    #[inline]
303    pub fn remove_style(&mut self) -> &mut Self {
304        self.style = None;
305        self
306    }
307
308    #[inline]
309    #[must_use]
310    pub fn color_scale(&self) -> Option<&ColorScale> {
311        self.color_scale.as_ref()
312    }
313
314    #[inline]
315    #[must_use]
316    #[deprecated(since = "3.0.0", note = "Use color_scale()")]
317    pub fn get_color_scale(&self) -> Option<&ColorScale> {
318        self.color_scale()
319    }
320
321    #[inline]
322    pub fn set_color_scale(&mut self, value: ColorScale) -> &mut Self {
323        self.color_scale = Some(value);
324        self
325    }
326
327    #[inline]
328    pub fn remove_color_scale(&mut self) -> &mut Self {
329        self.color_scale = None;
330        self
331    }
332
333    #[inline]
334    #[must_use]
335    pub fn data_bar(&self) -> Option<&DataBar> {
336        self.data_bar.as_ref()
337    }
338
339    #[inline]
340    #[must_use]
341    #[deprecated(since = "3.0.0", note = "Use data_bar()")]
342    pub fn get_data_bar(&self) -> Option<&DataBar> {
343        self.data_bar()
344    }
345
346    #[inline]
347    pub fn set_data_bar(&mut self, value: DataBar) -> &mut Self {
348        self.data_bar = Some(value);
349        self
350    }
351
352    #[inline]
353    pub fn remove_data_bar(&mut self) -> &mut Self {
354        self.data_bar = None;
355        self
356    }
357
358    #[inline]
359    #[must_use]
360    pub fn icon_set(&self) -> Option<&IconSet> {
361        self.icon_set.as_ref()
362    }
363
364    #[inline]
365    #[must_use]
366    #[deprecated(since = "3.0.0", note = "Use icon_set()")]
367    pub fn get_icon_set(&self) -> Option<&IconSet> {
368        self.icon_set()
369    }
370
371    #[inline]
372    pub fn set_icon_set(&mut self, value: IconSet) -> &mut Self {
373        self.icon_set = Some(value);
374        self
375    }
376
377    #[inline]
378    pub fn remove_icon_set(&mut self) -> &mut Self {
379        self.icon_set = None;
380        self
381    }
382
383    #[inline]
384    #[must_use]
385    pub fn formula(&self) -> Option<&Formula> {
386        self.formula.as_deref()
387    }
388
389    #[inline]
390    #[must_use]
391    #[deprecated(since = "3.0.0", note = "Use formula()")]
392    pub fn get_formula(&self) -> Option<&Formula> {
393        self.formula()
394    }
395
396    #[inline]
397    pub fn set_formula(&mut self, value: Formula) -> &mut Self {
398        self.formula = Some(Box::new(value));
399        self
400    }
401
402    #[inline]
403    pub fn remove_formula(&mut self) -> &mut Self {
404        self.formula = None;
405        self
406    }
407
408    pub(crate) fn set_attributes<R: std::io::BufRead>(
409        &mut self,
410        reader: &mut Reader<R>,
411        e: &BytesStart,
412        differential_formats: &DifferentialFormats,
413        empty_flag: bool,
414    ) {
415        set_string_from_xml!(self, e, r#type, "type");
416        set_string_from_xml!(self, e, operator, "operator");
417
418        if let Some(v) = get_attribute(e, b"dxfId") {
419            if let Ok(dxf_id) = v.parse::<usize>() {
420                let style = differential_formats.style(dxf_id);
421                self.set_style(style);
422            }
423        }
424
425        set_string_from_xml!(self, e, priority, "priority");
426        set_string_from_xml!(self, e, percent, "percent");
427        set_string_from_xml!(self, e, bottom, "bottom");
428        set_string_from_xml!(self, e, rank, "rank");
429        set_string_from_xml!(self, e, stop_if_true, "stopIfTrue");
430        set_string_from_xml!(self, e, std_dev, "stdDev");
431        set_string_from_xml!(self, e, time_period, "timePeriod");
432        set_string_from_xml!(self, e, above_average, "aboveAverage");
433        set_string_from_xml!(self, e, equal_average, "equalAverage");
434
435        if empty_flag {
436            return;
437        }
438
439        xml_read_loop!(
440            reader,
441            Event::Start(ref e) => {
442                match e.name().into_inner() {
443                    b"colorScale" => {
444                        let mut obj = ColorScale::default();
445                        obj.set_attributes(reader, e);
446                        self.color_scale = Some(obj);
447                    }
448                    b"dataBar" => {
449                        let mut obj = DataBar::default();
450                        obj.set_attributes(reader, e);
451                        self.data_bar = Some(obj);
452                    }
453                    b"iconSet" => {
454                        let mut obj = IconSet::default();
455                        obj.set_attributes(reader, e);
456                        self.icon_set = Some(obj);
457                    }
458                    b"formula" => {
459                        let mut obj = Formula::default();
460                        obj.set_attributes(reader, e);
461                        self.formula = Some(Box::new(obj));
462                    }
463                    _ => (),
464                }
465            },
466            Event::End(ref e) => {
467                if e.name().into_inner() == b"cfRule" {
468                    return
469                }
470            },
471            Event::Eof => return
472        );
473    }
474
475    pub(crate) fn write_to(
476        &self,
477        writer: &mut Writer<Cursor<Vec<u8>>>,
478        differential_formats: &mut DifferentialFormats,
479    ) {
480        let is_inner = self.color_scale.is_some()
481            || self.data_bar.is_some()
482            || self.icon_set.is_some()
483            || self.formula.is_some();
484
485        // cfRule
486        let mut attributes: crate::structs::AttrCollection = Vec::new();
487
488        let r#type = self.r#type.value_string();
489        if self.r#type.has_value() {
490            attributes.push(("type", r#type).into());
491        }
492
493        let operator = self.operator.value_string();
494        if self.operator.has_value() {
495            attributes.push(("operator", operator).into());
496        }
497
498        let dxf_id_str: String;
499        if let Some(v) = &self.style {
500            let dxf_id = differential_formats.set_style(v);
501            dxf_id_str = dxf_id.to_string();
502            attributes.push(("dxfId", &dxf_id_str).into());
503        }
504
505        let priority = self.priority.value_string();
506        if self.priority.has_value() {
507            attributes.push(("priority", &priority).into());
508        }
509
510        let percent = self.percent.value_string();
511        if self.percent.has_value() {
512            attributes.push(("percent", percent).into());
513        }
514
515        let bottom = self.bottom.value_string();
516        if self.bottom.has_value() {
517            attributes.push(("bottom", bottom).into());
518        }
519
520        let rank = self.rank.value_string();
521        if self.rank.has_value() {
522            attributes.push(("rank", &rank).into());
523        }
524
525        let stop_if_true = self.stop_if_true.value_string();
526        if self.stop_if_true.has_value() {
527            attributes.push(("stopIfTrue", stop_if_true).into());
528        }
529
530        let std_dev = self.std_dev.value_string();
531        if self.std_dev.has_value() {
532            attributes.push(("stdDev", &std_dev).into());
533        }
534
535        let time_period = self.time_period.value_string();
536        if self.time_period.has_value() {
537            attributes.push(("timePeriod", time_period).into());
538        }
539
540        let above_average = self.above_average.value_string();
541        if self.above_average.has_value() {
542            attributes.push(("aboveAverage", above_average).into());
543        }
544
545        let equal_average = self.equal_average.value_string();
546        if self.equal_average.has_value() {
547            attributes.push(("equalAverage", equal_average).into());
548        }
549
550        write_start_tag(writer, "cfRule", attributes, !is_inner);
551
552        if is_inner {
553            // colorScale
554            if let Some(v) = &self.color_scale {
555                v.write_to(writer);
556            }
557
558            // dataBar
559            if let Some(v) = &self.data_bar {
560                v.write_to(writer);
561            }
562
563            // iconSet
564            if let Some(v) = &self.icon_set {
565                v.write_to(writer);
566            }
567
568            // formula
569            if let Some(v) = &self.formula {
570                v.write_to(writer);
571            }
572
573            write_end_tag(writer, "cfRule");
574        }
575    }
576}