Skip to main content

umya_spreadsheet/structs/
conditional_formatting.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    ConditionalFormattingRule,
14    DifferentialFormats,
15    SequenceOfReferences,
16};
17use crate::{
18    reader::driver::{
19        get_attribute,
20        xml_read_loop,
21    },
22    traits::AdjustmentCoordinate,
23    writer::driver::{
24        write_end_tag,
25        write_start_tag,
26    },
27};
28
29#[derive(Default, Debug, Clone)]
30pub struct ConditionalFormatting {
31    sequence_of_references: SequenceOfReferences,
32    conditional_collection: Vec<ConditionalFormattingRule>,
33}
34
35impl ConditionalFormatting {
36    #[inline]
37    #[must_use]
38    pub fn sequence_of_references(&self) -> &SequenceOfReferences {
39        &self.sequence_of_references
40    }
41
42    #[inline]
43    #[must_use]
44    #[deprecated(since = "3.0.0", note = "Use sequence_of_references()")]
45    pub fn get_sequence_of_references(&self) -> &SequenceOfReferences {
46        self.sequence_of_references()
47    }
48
49    #[inline]
50    pub fn sequence_of_references_mut(&mut self) -> &mut SequenceOfReferences {
51        &mut self.sequence_of_references
52    }
53
54    #[inline]
55    #[deprecated(since = "3.0.0", note = "Use sequence_of_references_mut()")]
56    pub fn get_sequence_of_references_mut(&mut self) -> &mut SequenceOfReferences {
57        self.sequence_of_references_mut()
58    }
59
60    #[inline]
61    pub fn set_sequence_of_references(&mut self, value: SequenceOfReferences) -> &mut Self {
62        self.sequence_of_references = value;
63        self
64    }
65
66    #[inline]
67    #[must_use]
68    pub fn conditional_collection(&self) -> &[ConditionalFormattingRule] {
69        &self.conditional_collection
70    }
71
72    #[inline]
73    #[must_use]
74    #[deprecated(since = "3.0.0", note = "Use conditional_collection()")]
75    pub fn get_conditional_collection(&self) -> &[ConditionalFormattingRule] {
76        self.conditional_collection()
77    }
78
79    #[inline]
80    pub fn conditional_collection_mut(&mut self) -> &mut Vec<ConditionalFormattingRule> {
81        &mut self.conditional_collection
82    }
83
84    #[inline]
85    #[deprecated(since = "3.0.0", note = "Use conditional_collection_mut()")]
86    pub fn get_conditional_collection_mut(&mut self) -> &mut Vec<ConditionalFormattingRule> {
87        self.conditional_collection_mut()
88    }
89
90    #[inline]
91    pub fn set_conditional_collection(
92        &mut self,
93        value: impl Into<Vec<ConditionalFormattingRule>>,
94    ) -> &mut Self {
95        self.conditional_collection = value.into();
96        self
97    }
98
99    #[inline]
100    pub fn add_conditional_collection(&mut self, value: ConditionalFormattingRule) -> &mut Self {
101        self.conditional_collection.push(value);
102        self
103    }
104
105    pub(crate) fn set_attributes<R: std::io::BufRead>(
106        &mut self,
107        reader: &mut Reader<R>,
108        e: &BytesStart,
109        differential_formats: &DifferentialFormats,
110    ) {
111        if let Some(v) = get_attribute(e, b"sqref") {
112            self.sequence_of_references.set_sqref(v);
113        }
114
115        xml_read_loop!(
116            reader,
117            ref n @ (Event::Empty(ref e) | Event::Start(ref e)) => {
118                let is_empty = matches!(n, Event::Empty(_));
119                if e.name().into_inner() == b"cfRule" {
120                    let mut obj = ConditionalFormattingRule::default();
121                    obj.set_attributes(reader, e, differential_formats, is_empty);
122                    self.conditional_collection.push(obj);
123                }
124            },
125            Event::End(ref e) => {
126                if e.name().into_inner() == b"conditionalFormatting" {
127                    return
128                }
129            },
130            Event::Eof => panic!("Error: Could not find {} end element", "conditionalFormatting")
131        );
132    }
133
134    pub(crate) fn write_to(
135        &self,
136        writer: &mut Writer<Cursor<Vec<u8>>>,
137        differential_formats: &mut DifferentialFormats,
138    ) {
139        let is_inner = !self.conditional_collection.is_empty();
140
141        // conditionalFormatting
142        let mut attributes: crate::structs::AttrCollection = Vec::new();
143
144        let sequence_of_references = &self.sequence_of_references.get_sqref();
145        attributes.push(("sqref", sequence_of_references).into());
146
147        write_start_tag(writer, "conditionalFormatting", attributes, !is_inner);
148
149        if is_inner {
150            // cfRule
151            for v in &self.conditional_collection {
152                v.write_to(writer, differential_formats);
153            }
154
155            write_end_tag(writer, "conditionalFormatting");
156        }
157    }
158}
159impl AdjustmentCoordinate for ConditionalFormatting {
160    #[inline]
161    fn adjustment_insert_coordinate(
162        &mut self,
163        root_col_num: u32,
164        offset_col_num: u32,
165        root_row_num: u32,
166        offset_row_num: u32,
167    ) {
168        self.sequence_of_references.adjustment_insert_coordinate(
169            root_col_num,
170            offset_col_num,
171            root_row_num,
172            offset_row_num,
173        );
174    }
175
176    #[inline]
177    fn adjustment_remove_coordinate(
178        &mut self,
179        root_col_num: u32,
180        offset_col_num: u32,
181        root_row_num: u32,
182        offset_row_num: u32,
183    ) {
184        self.sequence_of_references.adjustment_remove_coordinate(
185            root_col_num,
186            offset_col_num,
187            root_row_num,
188            offset_row_num,
189        );
190    }
191
192    #[inline]
193    fn is_remove_coordinate(
194        &self,
195        root_col_num: u32,
196        offset_col_num: u32,
197        root_row_num: u32,
198        offset_row_num: u32,
199    ) -> bool {
200        self.sequence_of_references.is_remove_coordinate(
201            root_col_num,
202            offset_col_num,
203            root_row_num,
204            offset_row_num,
205        )
206    }
207}