1use get_size2::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 std::borrow::Borrow;
14use std::str::from_utf8;
15
16#[derive(Copy, Clone, Debug, Default, GetSize)]
18pub enum ValidationDisplay {
19 NoDisplay,
21 #[default]
23 Unsorted,
24 SortAscending,
26}
27
28impl TryFrom<&str> for ValidationDisplay {
29 type Error = OdsError;
30
31 fn try_from(value: &str) -> Result<Self, Self::Error> {
32 match value {
33 "unsorted" => Ok(ValidationDisplay::Unsorted),
34 "sort-ascending" => Ok(ValidationDisplay::SortAscending),
35 "none" => Ok(ValidationDisplay::NoDisplay),
36 _ => Err(OdsError::Parse(
37 "invalid table:display-list ",
38 Some(value.to_string()),
39 )),
40 }
41 }
42}
43
44impl TryFrom<&[u8]> for ValidationDisplay {
45 type Error = OdsError;
46
47 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
48 match value {
49 b"unsorted" => Ok(ValidationDisplay::Unsorted),
50 b"sort-ascending" => Ok(ValidationDisplay::SortAscending),
51 b"none" => Ok(ValidationDisplay::NoDisplay),
52 _ => Err(OdsError::Parse(
53 "invalid table:display-list ",
54 Some(from_utf8(value)?.into()),
55 )),
56 }
57 }
58}
59
60#[derive(Clone, Debug, GetSize)]
62pub struct ValidationHelp {
63 display: bool,
64 title: Option<String>,
65 text: Option<Box<TextTag>>,
66}
67
68impl Default for ValidationHelp {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74impl ValidationHelp {
75 pub fn new() -> Self {
77 Self {
78 display: true,
79 title: None,
80 text: None,
81 }
82 }
83
84 pub fn set_display(&mut self, display: bool) {
86 self.display = display;
87 }
88
89 pub fn display(&self) -> bool {
91 self.display
92 }
93
94 pub fn set_title(&mut self, title: Option<String>) {
96 self.title = title;
97 }
98
99 pub fn title(&self) -> Option<&str> {
101 self.title.as_deref()
102 }
103
104 pub fn set_text(&mut self, text: Option<TextTag>) {
106 if let Some(txt) = text {
107 self.text = Some(Box::new(txt));
108 } else {
109 self.text = None;
110 };
111 }
112
113 pub fn text(&self) -> Option<&TextTag> {
115 self.text.as_deref()
116 }
117}
118
119#[derive(Copy, Clone, Debug, GetSize)]
123pub enum MessageType {
124 Error,
126 Warning,
128 Info,
130}
131
132impl Display for MessageType {
133 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
134 match self {
135 MessageType::Error => write!(f, "stop"),
136 MessageType::Warning => write!(f, "warning"),
137 MessageType::Info => write!(f, "information"),
138 }
139 }
140}
141
142#[derive(Clone, Debug, GetSize)]
144pub struct ValidationError {
145 display: bool,
146 msg_type: MessageType,
147 title: Option<String>,
148 text: Option<Box<TextTag>>,
149}
150
151impl Default for ValidationError {
152 fn default() -> Self {
153 Self::new()
154 }
155}
156
157impl ValidationError {
158 pub fn new() -> Self {
160 Self {
161 display: true,
162 msg_type: MessageType::Error,
163 title: None,
164 text: None,
165 }
166 }
167
168 pub fn set_display(&mut self, display: bool) {
170 self.display = display;
171 }
172
173 pub fn display(&self) -> bool {
175 self.display
176 }
177
178 pub fn set_msg_type(&mut self, msg_type: MessageType) {
180 self.msg_type = msg_type;
181 }
182
183 pub fn msg_type(&self) -> &MessageType {
185 &self.msg_type
186 }
187
188 pub fn set_title(&mut self, title: Option<String>) {
190 self.title = title;
191 }
192
193 pub fn title(&self) -> Option<&str> {
195 self.title.as_deref()
196 }
197
198 pub fn set_text(&mut self, text: Option<TextTag>) {
200 if let Some(txt) = text {
201 self.text = Some(Box::new(txt));
202 } else {
203 self.text = None;
204 };
205 }
206
207 pub fn text(&self) -> Option<&TextTag> {
209 self.text.as_deref()
210 }
211}
212
213style_ref2!(ValidationRef);
214
215#[derive(Clone, Debug, Default, GetSize)]
220pub struct Validation {
221 name: String,
222 condition: Condition,
223 base_cell: CellRef,
224 allow_empty: bool,
225 display_list: ValidationDisplay,
226 err: Option<ValidationError>,
227 help: Option<ValidationHelp>,
228}
229
230impl Validation {
231 pub fn new() -> Self {
233 Self {
234 name: Default::default(),
235 condition: Default::default(),
236 base_cell: Default::default(),
237 allow_empty: true,
238 display_list: Default::default(),
239 err: Some(ValidationError {
240 display: true,
241 msg_type: MessageType::Error,
242 title: None,
243 text: None,
244 }),
245 help: None,
246 }
247 }
248
249 pub fn set_name<S: AsRef<str>>(&mut self, name: S) {
251 self.name = name.as_ref().to_string();
252 }
253
254 pub fn name(&self) -> &str {
256 self.name.as_str()
257 }
258
259 pub fn validation_ref(&self) -> ValidationRef {
261 ValidationRef::from(self.name.clone())
262 }
263
264 pub fn set_condition(&mut self, cond: Condition) {
266 self.condition = cond;
267 }
268
269 pub fn condition(&self) -> &Condition {
271 &self.condition
272 }
273
274 pub fn set_base_cell(&mut self, base: CellRef) {
278 self.base_cell = base;
279 }
280
281 pub fn base_cell(&self) -> &CellRef {
283 &self.base_cell
284 }
285
286 pub fn set_allow_empty(&mut self, allow: bool) {
288 self.allow_empty = allow;
289 }
290
291 pub fn allow_empty(&self) -> bool {
293 self.allow_empty
294 }
295
296 pub fn set_display(&mut self, display: ValidationDisplay) {
298 self.display_list = display;
299 }
300
301 pub fn display(&self) -> ValidationDisplay {
303 self.display_list
304 }
305
306 pub fn set_err(&mut self, err: Option<ValidationError>) {
308 self.err = err;
309 }
310
311 pub fn err(&self) -> Option<&ValidationError> {
313 self.err.as_ref()
314 }
315
316 pub fn set_help(&mut self, help: Option<ValidationHelp>) {
318 self.help = help;
319 }
320
321 pub fn help(&self) -> Option<&ValidationHelp> {
323 self.help.as_ref()
324 }
325}