1use serde::{ser, Serialize, Serializer};
2use std::collections::BTreeMap;
3use std::hash::Hash;
4
5use crate::{Path, Root};
6
7pub trait Validate {
9 fn validate<P, R>(&self, _root: &Root, _path: P, _report: &mut R)
11 where
12 P: Fn() -> Path,
13 R: FnMut(&dyn Fn() -> Path, Error),
14 {
15 }
17}
18
19#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
21pub enum Error {
22 IndexOutOfBounds,
24
25 Invalid,
27
28 Missing,
30
31 Oversize,
33
34 Unsupported,
36}
37
38#[derive(Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
40pub enum Checked<T> {
41 Valid(T),
43
44 Invalid,
46}
47
48impl<T> Checked<T> {
49 pub fn as_ref(&self) -> Checked<&T> {
51 match *self {
52 Checked::Valid(ref item) => Checked::Valid(item),
53 Checked::Invalid => Checked::Invalid,
54 }
55 }
56
57 pub fn unwrap(self) -> T {
63 match self {
64 Checked::Valid(item) => item,
65 Checked::Invalid => panic!("attempted to unwrap an invalid item"),
66 }
67 }
68}
69
70impl<T: Serialize> Serialize for Checked<T> {
71 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
72 where
73 S: Serializer,
74 {
75 match *self {
76 Checked::Valid(ref item) => item.serialize(serializer),
77 Checked::Invalid => Err(ser::Error::custom("invalid item")),
78 }
79 }
80}
81
82impl<T: Clone> Clone for Checked<T> {
83 fn clone(&self) -> Self {
84 match *self {
85 Checked::Valid(ref item) => Checked::Valid(item.clone()),
86 Checked::Invalid => Checked::Invalid,
87 }
88 }
89}
90
91impl<T: Copy> Copy for Checked<T> {}
92
93impl<T: Default> Default for Checked<T> {
94 fn default() -> Self {
95 Checked::Valid(T::default())
96 }
97}
98
99impl<T> Validate for Checked<T> {
100 fn validate<P, R>(&self, _root: &Root, path: P, report: &mut R)
101 where
102 P: Fn() -> Path,
103 R: FnMut(&dyn Fn() -> Path, Error),
104 {
105 match *self {
106 Checked::Valid(_) => {}
107 Checked::Invalid => report(&path, Error::Invalid),
108 }
109 }
110}
111
112#[derive(
114 Clone,
115 Copy,
116 Debug,
117 Default,
118 Eq,
119 Hash,
120 PartialEq,
121 serde_derive::Deserialize,
122 serde_derive::Serialize,
123)]
124pub struct USize64(pub u64);
125
126impl From<u64> for USize64 {
127 fn from(value: u64) -> Self {
128 Self(value)
129 }
130}
131
132impl From<usize> for USize64 {
133 fn from(value: usize) -> Self {
134 Self(value as u64)
135 }
136}
137
138impl Validate for USize64 {
139 fn validate<P, R>(&self, _root: &Root, path: P, report: &mut R)
140 where
141 P: Fn() -> Path,
142 R: FnMut(&dyn Fn() -> Path, Error),
143 {
144 if usize::try_from(self.0).is_err() {
145 report(&path, Error::Oversize);
146 }
147 }
148}
149
150impl<K: ToString + Validate, V: Validate> Validate for BTreeMap<K, V> {
151 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
152 where
153 P: Fn() -> Path,
154 R: FnMut(&dyn Fn() -> Path, Error),
155 {
156 for (key, value) in self.iter() {
157 key.validate(root, || path().key(&key.to_string()), report);
158 value.validate(root, || path().key(&key.to_string()), report);
159 }
160 }
161}
162
163impl Validate for serde_json::Map<String, serde_json::Value> {
164 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
165 where
166 P: Fn() -> Path,
167 R: FnMut(&dyn Fn() -> Path, Error),
168 {
169 for (key, value) in self.iter() {
170 key.validate(root, || path().key(&key.to_string()), report);
171 value.validate(root, || path().key(&key.to_string()), report);
172 }
173 }
174}
175
176impl<T: Validate> Validate for Option<T> {
177 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
178 where
179 P: Fn() -> Path,
180 R: FnMut(&dyn Fn() -> Path, Error),
181 {
182 if let Some(value) = self.as_ref() {
183 value.validate(root, path, report);
184 }
185 }
186}
187
188impl<T: Validate> Validate for Vec<T> {
189 fn validate<P, R>(&self, root: &Root, path: P, report: &mut R)
190 where
191 P: Fn() -> Path,
192 R: FnMut(&dyn Fn() -> Path, Error),
193 {
194 for (index, value) in self.iter().enumerate() {
195 value.validate(root, || path().index(index), report);
196 }
197 }
198}
199
200impl Validate for std::boxed::Box<serde_json::value::RawValue> {
201 fn validate<P, R>(&self, _: &Root, _: P, _: &mut R)
202 where
203 P: Fn() -> Path,
204 R: FnMut(&dyn Fn() -> Path, Error),
205 {
206 }
208}
209
210impl std::error::Error for Error {}
211
212impl std::fmt::Display for Error {
213 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
214 write!(
215 f,
216 "{}",
217 match *self {
218 Error::IndexOutOfBounds => "Index out of bounds",
219 Error::Invalid => "Invalid value",
220 Error::Missing => "Missing data",
221 Error::Oversize => "Size exceeds system limits",
222 Error::Unsupported => "Unsupported extension",
223 }
224 )
225 }
226}
227
228impl Validate for bool {}
230impl Validate for u32 {}
231impl Validate for i32 {}
232impl Validate for f32 {}
233impl Validate for [f32; 3] {}
234impl Validate for [f32; 4] {}
235impl Validate for [f32; 16] {}
236impl Validate for () {}
237impl Validate for String {}
238impl Validate for serde_json::Value {}