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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*!
Validating JSON-like data with support for multiple validators
*/
pub(self) use crate::{Error, Result};
pub(self) use std::path::Path;
macro_rules! decl_standards {
($(
$(#[$attr:meta])*
$type:ident $name:ident;
)*) => {
/// JSON Schema standard
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Standard {
$(
$(#[$attr])*
$type,
)*
}
impl std::str::FromStr for Standard {
type Err = &'static str;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(match s {
$(
$(#[$attr])*
stringify!($name) => Self::$type,
)*
_ => return Err("unknown"),
})
}
}
impl std::fmt::Display for Standard {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
$(
$(#[$attr])*
Self::$type => stringify!($name).fmt(f),
)*
}
}
}
impl Standard {
/// List of all variants
pub const LIST: &'static [&'static str] = &[
$(
$(#[$attr])*
stringify!($name),
)*
];
}
};
}
macro_rules! decl_validators {
($(
$(#[$attr:meta])*
$type:ident $name:ident;
)*) => {
// Define modules
$(
$(#[$attr])*
mod $name;
)*
/// Supported validators
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Validator {
$(
$(#[$attr])*
$type,
)*
}
impl std::str::FromStr for Validator {
type Err = &'static str;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
Ok(match s {
$(
$(#[$attr])*
stringify!($name) => Self::$type,
)*
_ => return Err("unknown"),
})
}
}
impl std::fmt::Display for Validator {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
$(
$(#[$attr])*
Self::$type => stringify!($name).fmt(f),
)*
}
}
}
impl Validator {
/// List of all variants
pub const LIST: &'static [&'static str] = &[
$(
$(#[$attr])*
stringify!($name),
)*
];
/// Compile JSON schema
pub fn compile_schema<'c>(&self, schema: &'c json::Value, std: Option<Standard>) -> Result<CompiledSchema<'c>> {
match self {
$(
$(#[$attr])*
Self::$type => $name::CompiledSchema::compile(schema, std).map(CompiledSchema::$type),
)*
}
}
}
/// Compiled schema
pub enum CompiledSchema<'c> {
$(
$(#[$attr])*
$type($name::CompiledSchema<'c>),
)*
}
impl<'c> CompiledSchema<'c> {
/// Validate JSON data
pub fn validate_data(&self, path: &Path, data: &json::Value, quiet: bool) -> Result<u32> {
match self {
$(
$(#[$attr])*
Self::$type(compiled_schema) => compiled_schema.validate(path, data, quiet),
)*
}
}
}
};
}
decl_standards! {
Draft4 darft4;
Draft6 draft6;
Draft7 draft7;
}
decl_validators! {
#[cfg(feature = "valico")]
Valico valico;
#[cfg(feature = "jsonschema")]
JsonSchema jsonschema;
#[cfg(feature = "jsonschema-valid")]
JsonSchemaValid jsonschema_valid;
}