1use crate::Validator;
2use std::fmt;
3use std::ops::Deref;
4
5#[derive(Debug)]
33pub struct Valid<T: Validator>(T);
34
35impl<T: Validator> Valid<T> {
36 #[allow(dead_code)]
37 pub fn new(val: T) -> Result<Self, String> {
38 val.check_validity()?;
39 Ok(Valid(val))
40 }
41
42 #[allow(dead_code)]
43 pub fn into_inner(self) -> T {
44 self.0
45 }
46}
47
48impl<T: Validator> Deref for Valid<T> {
49 type Target = T;
50
51 fn deref(&self) -> &Self::Target {
52 &self.0
53 }
54}
55
56impl<T: Validator + fmt::Display> fmt::Display for Valid<T> {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 fmt::Display::fmt(&self.0, f)
59 }
60}
61
62#[cfg(feature = "serde")]
63#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
64impl<'a, T: Validator + serde::Deserialize<'a>> serde::Deserialize<'a> for Valid<T> {
65 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66 where
67 D: serde::Deserializer<'a>,
68 {
69 let v = T::deserialize(deserializer)?;
70 Valid::new(v).map_err(serde::de::Error::custom)
71 }
72}
73
74#[cfg(feature = "serde")]
75#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
76impl<T: Validator + serde::Serialize> serde::Serialize for Valid<T> {
77 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: serde::Serializer,
80 {
81 self.0.serialize(serializer)
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use crate::valid::Valid;
88 use crate::Validator;
89 use claim::{assert_err, assert_ok};
90
91 #[derive(Debug)]
92 struct ValidTest(i32);
93
94 impl Validator for ValidTest {
95 fn check_validity(&self) -> Result<(), String> {
96 match self.0.is_positive() {
97 true => Ok(()),
98 false => Err(String::from("Need to be positive")),
99 }
100 }
101 }
102
103 #[test]
104 fn valid_ok() {
105 assert_ok!(Valid::new(ValidTest(1)));
106 }
107
108 #[test]
109 fn valid_err() {
110 assert_err!(Valid::new(ValidTest(-1)));
111 }
112
113 #[cfg(feature = "serde")]
114 mod serde_tests {
115 use crate::valid::Valid;
116 use crate::Validator;
117 use claim::{assert_err, assert_ok};
118 use serde_derive::{Deserialize, Serialize};
119
120 #[derive(Deserialize, Serialize, Debug)]
121 struct Int {
122 val: i32,
123 }
124
125 impl Validator for Int {
126 fn check_validity(&self) -> Result<(), String> {
127 match self.val.is_positive() {
128 true => Ok(()),
129 false => Err(String::from("Need to be positive")),
130 }
131 }
132 }
133
134 #[test]
135 fn valid_serde_ok() {
136 let serialized = "{\"val\":1}";
137 let res: serde_json::Result<Valid<Int>> = serde_json::from_str(serialized);
138 assert_ok!(res);
139 }
140
141 #[test]
142 fn valid_serde_err() {
143 let serialized = "{\"val\":-1}";
144 let res: serde_json::Result<Valid<Int>> = serde_json::from_str(serialized);
145 assert_err!(res);
146 }
147
148 #[test]
149 fn valid_serde_serialize() {
150 let valid_int = Valid::new(Int { val: 1 }).unwrap();
151 let serialized = serde_json::to_string(&valid_int).unwrap();
152 assert_eq!(&serialized, "{\"val\":1}")
153 }
154 }
155}