1use get_size::GetSize;
6use std::convert::TryFrom;
7use std::fmt::{Display, Formatter};
8
9use crate::condition::Condition;
10use crate::style::AnyStyleRef;
11use crate::text::TextTag;
12use crate::{CellRef, OdsError};
13use get_size_derive::GetSize;
14use std::borrow::Borrow;
15use std::str::from_utf8;
16
17#[derive(Copy, Clone, Debug, Default, GetSize)]
19pub enum ValidationDisplay {
20 NoDisplay,
22 #[default]
24 Unsorted,
25 SortAscending,
27}
28
29impl TryFrom<&str> for ValidationDisplay {
30 type Error = OdsError;
31
32 fn try_from(value: &str) -> Result<Self, Self::Error> {
33 match value {
34 "unsorted" => Ok(ValidationDisplay::Unsorted),
35 "sort-ascending" => Ok(ValidationDisplay::SortAscending),
36 "none" => Ok(ValidationDisplay::NoDisplay),
37 _ => Err(OdsError::Parse(
38 "invalid table:display-list ",
39 Some(value.to_string()),
40 )),
41 }
42 }
43}
44
45impl TryFrom<&[u8]> for ValidationDisplay {
46 type Error = OdsError;
47
48 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
49 match value {
50 b"unsorted" => Ok(ValidationDisplay::Unsorted),
51 b"sort-ascending" => Ok(ValidationDisplay::SortAscending),
52 b"none" => Ok(ValidationDisplay::NoDisplay),
53 _ => Err(OdsError::Parse(
54 "invalid table:display-list ",
55 Some(from_utf8(value)?.into()),
56 )),
57 }
58 }
59}
60
61#[derive(Clone, Debug, GetSize)]
63pub struct ValidationHelp {
64 display: bool,
65 title: Option<String>,
66 text: Option<Box<TextTag>>,
67}
68
69impl Default for ValidationHelp {
70 fn default() -> Self {
71 Self::new()
72 }
73}
74
75impl ValidationHelp {
76 pub fn new() -> Self {
78 Self {
79 display: true,
80 title: None,
81 text: None,
82 }
83 }
84
85 pub fn set_display(&mut self, display: bool) {
87 self.display = display;
88 }
89
90 pub fn display(&self) -> bool {
92 self.display
93 }
94
95 pub fn set_title(&mut self, title: Option<String>) {
97 self.title = title;
98 }
99
100 pub fn title(&self) -> Option<&str> {
102 self.title.as_deref()
103 }
104
105 pub fn set_text(&mut self, text: Option<TextTag>) {
107 if let Some(txt) = text {
108 self.text = Some(Box::new(txt));
109 } else {
110 self.text = None;
111 };
112 }
113
114 pub fn text(&self) -> Option<&TextTag> {
116 self.text.as_deref()
117 }
118}
119
120#[derive(Copy, Clone, Debug, GetSize)]
124pub enum MessageType {
125 Error,
127 Warning,
129 Info,
131}
132
133impl Display for MessageType {
134 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
135 match self {
136 MessageType::Error => write!(f, "stop"),
137 MessageType::Warning => write!(f, "warning"),
138 MessageType::Info => write!(f, "information"),
139 }
140 }
141}
142
143#[derive(Clone, Debug, GetSize)]
145pub struct ValidationError {
146 display: bool,
147 msg_type: MessageType,
148 title: Option<String>,
149 text: Option<Box<TextTag>>,
150}
151
152impl Default for ValidationError {
153 fn default() -> Self {
154 Self::new()
155 }
156}
157
158impl ValidationError {
159 pub fn new() -> Self {
161 Self {
162 display: true,
163 msg_type: MessageType::Error,
164 title: None,
165 text: None,
166 }
167 }
168
169 pub fn set_display(&mut self, display: bool) {
171 self.display = display;
172 }
173
174 pub fn display(&self) -> bool {
176 self.display
177 }
178
179 pub fn set_msg_type(&mut self, msg_type: MessageType) {
181 self.msg_type = msg_type;
182 }
183
184 pub fn msg_type(&self) -> &MessageType {
186 &self.msg_type
187 }
188
189 pub fn set_title(&mut self, title: Option<String>) {
191 self.title = title;
192 }
193
194 pub fn title(&self) -> Option<&str> {
196 self.title.as_deref()
197 }
198
199 pub fn set_text(&mut self, text: Option<TextTag>) {
201 if let Some(txt) = text {
202 self.text = Some(Box::new(txt));
203 } else {
204 self.text = None;
205 };
206 }
207
208 pub fn text(&self) -> Option<&TextTag> {
210 self.text.as_deref()
211 }
212}
213
214style_ref2!(ValidationRef);
215
216#[derive(Clone, Debug, Default, GetSize)]
221pub struct Validation {
222 name: String,
223 condition: Condition,
224 base_cell: CellRef,
225 allow_empty: bool,
226 display_list: ValidationDisplay,
227 err: Option<ValidationError>,
228 help: Option<ValidationHelp>,
229}
230
231impl Validation {
232 pub fn new() -> Self {
234 Self {
235 name: Default::default(),
236 condition: Default::default(),
237 base_cell: Default::default(),
238 allow_empty: true,
239 display_list: Default::default(),
240 err: Some(ValidationError {
241 display: true,
242 msg_type: MessageType::Error,
243 title: None,
244 text: None,
245 }),
246 help: None,
247 }
248 }
249
250 pub fn set_name<S: AsRef<str>>(&mut self, name: S) {
252 self.name = name.as_ref().to_string();
253 }
254
255 pub fn name(&self) -> &str {
257 self.name.as_str()
258 }
259
260 pub fn validation_ref(&self) -> ValidationRef {
262 ValidationRef::from(self.name.clone())
263 }
264
265 pub fn set_condition(&mut self, cond: Condition) {
267 self.condition = cond;
268 }
269
270 pub fn condition(&self) -> &Condition {
272 &self.condition
273 }
274
275 pub fn set_base_cell(&mut self, base: CellRef) {
279 self.base_cell = base;
280 }
281
282 pub fn base_cell(&self) -> &CellRef {
284 &self.base_cell
285 }
286
287 pub fn set_allow_empty(&mut self, allow: bool) {
289 self.allow_empty = allow;
290 }
291
292 pub fn allow_empty(&self) -> bool {
294 self.allow_empty
295 }
296
297 pub fn set_display(&mut self, display: ValidationDisplay) {
299 self.display_list = display;
300 }
301
302 pub fn display(&self) -> ValidationDisplay {
304 self.display_list
305 }
306
307 pub fn set_err(&mut self, err: Option<ValidationError>) {
309 self.err = err;
310 }
311
312 pub fn err(&self) -> Option<&ValidationError> {
314 self.err.as_ref()
315 }
316
317 pub fn set_help(&mut self, help: Option<ValidationHelp>) {
319 self.help = help;
320 }
321
322 pub fn help(&self) -> Option<&ValidationHelp> {
324 self.help.as_ref()
325 }
326}