umya_spreadsheet/structs/
border.rs1use super::BorderStyleValues;
3use super::Color;
4use super::EnumValue;
5use crate::reader::driver::*;
6use crate::writer::driver::*;
7use md5::Digest;
8use quick_xml::events::{BytesStart, Event};
9use quick_xml::Reader;
10use quick_xml::Writer;
11use std::io::Cursor;
12
13#[derive(Default, Debug, Clone, PartialEq, PartialOrd)]
14pub struct Border {
15 color: Color,
16 style: EnumValue<BorderStyleValues>,
17}
18
19impl Border {
20 #[inline]
21 pub fn get_color(&self) -> &Color {
22 &self.color
23 }
24
25 #[inline]
26 pub fn get_color_mut(&mut self) -> &mut Color {
27 &mut self.color
28 }
29
30 #[inline]
31 pub fn set_color(&mut self, value: Color) -> &mut Self {
32 self.color = value;
33 self
34 }
35
36 #[inline]
37 pub fn get_style(&self) -> &BorderStyleValues {
38 self.style.get_value()
39 }
40
41 #[inline]
42 pub fn set_style(&mut self, value: BorderStyleValues) -> &mut Self {
43 self.style.set_value(value);
44 self
45 }
46
47 pub const BORDER_NONE: &'static str = "none";
49 pub const BORDER_DASHDOT: &'static str = "dashDot";
50 pub const BORDER_DASHDOTDOT: &'static str = "dashDotDot";
51 pub const BORDER_DASHED: &'static str = "dashed";
52 pub const BORDER_DOTTED: &'static str = "dotted";
53 pub const BORDER_DOUBLE: &'static str = "double";
54 pub const BORDER_HAIR: &'static str = "hair";
55 pub const BORDER_MEDIUM: &'static str = "medium";
56 pub const BORDER_MEDIUMDASHDOT: &'static str = "mediumDashDot";
57 pub const BORDER_MEDIUMDASHDOTDOT: &'static str = "mediumDashDotDot";
58 pub const BORDER_MEDIUMDASHED: &'static str = "mediumDashed";
59 pub const BORDER_SLANTDASHDOT: &'static str = "slantDashDot";
60 pub const BORDER_THICK: &'static str = "thick";
61 pub const BORDER_THIN: &'static str = "thin";
62
63 #[inline]
64 pub fn get_border_style(&self) -> &str {
65 self.style.get_value_string()
66 }
67 #[inline]
68 pub fn set_border_style<S: Into<String>>(&mut self, value: S) {
69 self.style.set_value_string(value);
70 }
71
72 pub(crate) fn get_hash_code(&self) -> String {
73 format!(
74 "{:x}",
75 md5::Md5::digest(format!(
76 "{}{}",
77 &self.style.get_value_string(),
78 &self.get_color().get_hash_code()
79 ))
80 )
81 }
82
83 #[inline]
85 pub(crate) fn is_visually_empty(&self) -> bool {
86 self.style.get_value() == &BorderStyleValues::None
87 }
88
89 pub(crate) fn set_attributes<R: std::io::BufRead>(
90 &mut self,
91 reader: &mut Reader<R>,
92 e: &BytesStart,
93 empty_flg: bool,
94 ) {
95 set_string_from_xml!(self, e, style, "style");
96
97 if empty_flg {
98 return;
99 }
100
101 xml_read_loop!(
102 reader,
103 Event::Empty(ref e) => {
104 if e.name().into_inner() == b"color" {
105 self.color.set_attributes(reader, e, true);
106 }
107 },
108 Event::End(ref e) => {
109 match e.name().into_inner() {
110 b"left" => return,
111 b"right" => return,
112 b"top" => return,
113 b"bottom" => return,
114 b"diagonal" => return,
115 b"vertical" => return,
116 b"horizontal" => return,
117 _ => (),
118 }
119 },
120 Event::Eof => panic!(
121 "Error: Could not find {} end element",
122 "left,right,top,bottom,diagonal,vertical,horizontal"
123 )
124 );
125 }
126
127 #[inline]
128 pub(crate) fn write_to_left(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
129 self.write_to(writer, "left");
130 }
131
132 #[inline]
133 pub(crate) fn write_to_right(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
134 self.write_to(writer, "right");
135 }
136
137 #[inline]
138 pub(crate) fn write_to_top(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
139 self.write_to(writer, "top");
140 }
141
142 #[inline]
143 pub(crate) fn write_to_bottom(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
144 self.write_to(writer, "bottom");
145 }
146
147 #[inline]
148 pub(crate) fn write_to_diagonal(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
149 self.write_to(writer, "diagonal");
150 }
151
152 #[inline]
153 pub(crate) fn write_to_vertical(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
154 self.write_to(writer, "vertical");
155 }
156
157 #[inline]
158 pub(crate) fn write_to_horizontal(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
159 self.write_to(writer, "horizontal");
160 }
161
162 pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>, tag_name: &str) {
163 let mut attributes: Vec<(&str, &str)> = Vec::new();
165 if self.style.has_value() {
166 attributes.push(("style", self.style.get_value_string()));
167 }
168
169 let empty_flag = !self.color.has_value();
170 write_start_tag(writer, tag_name, attributes, empty_flag);
171
172 if !empty_flag {
173 self.color.write_to_color(writer);
175
176 write_end_tag(writer, tag_name);
177 }
178 }
179}