1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use std::borrow::Cow;
use validator::ValidationError;
pub(crate) type ValidationResult = Result<(), validator::ValidationErrors>;
pub(crate) type ValidatorResult = Result<(), validator::ValidationError>;
pub(crate) fn error<StrIsh: AsRef<str>>(kind: &'static str,
msg: StrIsh)
-> ValidationError {
let mut error = ValidationError::new(kind);
error.add_param(Cow::from("message"),
&serde_json::Value::String(msg.as_ref().to_string()));
error
}
pub(crate) fn below_len(context: &'static str,
max_len: u16,
text: impl Long)
-> ValidatorResult {
let len = text.len();
if len >= max_len.into() {
Err(error(context,
format!("{} has a max length of {}, got {}",
context, max_len, len)))
} else {
Ok(())
}
}
pub(crate) fn len(context: &'static str,
range: impl std::ops::RangeBounds<usize> + std::fmt::Debug,
text: impl Long)
-> ValidatorResult {
let len = text.len();
if !range.contains(&len) {
Err(error(context,
format!("{} must be within range {:#?}, got {}",
context, range, len)))
} else {
Ok(())
}
}
pub(crate) trait Long {
fn len(&self) -> usize;
}
impl Long for &crate::text::Text {
fn len(&self) -> usize {
self.as_ref().len()
}
}
impl Long for &str {
fn len(&self) -> usize {
str::len(self)
}
}
impl<'a> Long for &Cow<'a, str> {
fn len(&self) -> usize {
str::len(self)
}
}
impl<T> Long for &[T] {
fn len(&self) -> usize {
self.as_ref().len()
}
}