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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use std::fmt::{self,Display,Formatter};
#[cfg(test)] mod tst;
use super::ArgsError;
pub trait Validation {
type T;
fn error(&self, value: &Self::T) -> ArgsError;
fn is_valid(&self, value: &Self::T) -> bool;
fn is_invalid(&self, value: &Self::T) -> bool { !self.is_valid(value) }
}
pub enum Order {
GreaterThan,
GreaterThanOrEqual,
LessThan,
LessThanOrEqual
}
impl Order {
pub fn compare<T: PartialOrd>(&self, bound: &T, value: &T) -> bool {
match *self {
Order::GreaterThan => { value > bound },
Order::GreaterThanOrEqual => { value >= bound },
Order::LessThan => { value < bound },
Order::LessThanOrEqual => { value <= bound }
}
}
}
impl Display for Order {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let display = match *self {
Order::GreaterThan => { "greater than" },
Order::GreaterThanOrEqual => { "greater than or equal to" },
Order::LessThan => { "less than" },
Order::LessThanOrEqual => { "less than or equal to" }
};
write!(f, "{}", display)
}
}
pub struct OrderValidation<O: Clone + Display + PartialOrd> {
bound: O,
order: Order
}
impl<O: Clone + Display + PartialOrd> OrderValidation<O> {
pub fn new(order: Order, bound: O) -> OrderValidation<O> {
OrderValidation { bound: bound.clone(), order: order }
}
}
impl<O: Clone + Display + PartialOrd> Validation for OrderValidation<O> {
type T = O;
fn error(&self, value: &O) -> ArgsError {
ArgsError::new("order invalid", &format!("{} is not {} {}", value, self.order, self.bound))
}
fn is_valid(&self, value: &O) -> bool {
self.order.compare(&self.bound, value)
}
}