1use lazy_static::lazy_static;
5use serde_json::Value;
6
7use crate::format;
8use crate::format::FormatChecker;
9use crate::validators;
10use crate::validators::Validator;
11
12#[derive(Debug, Copy, Clone, PartialEq, Eq)]
14pub enum Draft {
15 Draft4,
17
18 Draft6,
20
21 Draft7,
23}
24
25impl Draft {
26 pub(crate) fn get_validator(self, key: &str) -> Option<Validator> {
27 match self {
28 Draft::Draft4 => draft4::get_validator(key),
29 Draft::Draft6 => draft6::get_validator(key),
30 Draft::Draft7 => draft7::get_validator(key),
31 }
32 }
33
34 pub fn get_schema(self) -> &'static Value {
36 match self {
37 Draft::Draft7 => draft7::get_schema(),
38 Draft::Draft6 => draft6::get_schema(),
39 Draft::Draft4 => draft4::get_schema(),
40 }
41 }
42
43 pub(crate) fn get_format_checker(self, format: &str) -> Option<FormatChecker> {
45 match self {
46 Draft::Draft4 => draft4::get_format_checker(format),
47 Draft::Draft6 => draft6::get_format_checker(format),
48 Draft::Draft7 => draft7::get_format_checker(format),
49 }
50 }
51
52 pub fn get_draft_number(self) -> u8 {
54 match self {
55 Draft::Draft4 => 4,
56 Draft::Draft6 => 6,
57 Draft::Draft7 => 7,
58 }
59 }
60}
61
62mod draft7 {
63 use super::*;
64
65 pub(super) fn get_validator(key: &str) -> Option<Validator> {
66 match key {
67 "$ref" => Some(validators::ref_ as Validator),
68 "additionalItems" => Some(validators::additionalItems as Validator),
69 "additionalProperties" => Some(validators::additionalProperties as Validator),
70 "allOf" => Some(validators::allOf as Validator),
71 "anyOf" => Some(validators::anyOf as Validator),
72 "const" => Some(validators::const_ as Validator),
73 "contains" => Some(validators::contains as Validator),
74 "dependencies" => Some(validators::dependencies as Validator),
75 "enum" => Some(validators::enum_ as Validator),
76 "exclusiveMaximum" => Some(validators::exclusiveMaximum as Validator),
77 "exclusiveMinimum" => Some(validators::exclusiveMinimum as Validator),
78 "format" => Some(validators::format as Validator),
79 "if" => Some(validators::if_ as Validator),
80 "items" => Some(validators::items as Validator),
81 "maxItems" => Some(validators::maxItems as Validator),
82 "maxLength" => Some(validators::maxLength as Validator),
83 "maxProperties" => Some(validators::maxProperties as Validator),
84 "maximum" => Some(validators::maximum as Validator),
85 "minItems" => Some(validators::minItems as Validator),
86 "minLength" => Some(validators::minLength as Validator),
87 "minProperties" => Some(validators::minProperties as Validator),
88 "minimum" => Some(validators::minimum as Validator),
89 "multipleOf" => Some(validators::multipleOf as Validator),
90 "not" => Some(validators::not as Validator),
91 "oneOf" => Some(validators::oneOf as Validator),
92 "pattern" => Some(validators::pattern as Validator),
93 "patternProperties" => Some(validators::patternProperties as Validator),
94 "properties" => Some(validators::properties as Validator),
95 "propertyNames" => Some(validators::propertyNames as Validator),
96 "required" => Some(validators::required as Validator),
97 "type" => Some(validators::type_ as Validator),
98 "uniqueItems" => Some(validators::uniqueItems as Validator),
99 _ => None,
100 }
101 }
102
103 pub(super) fn get_schema() -> &'static Value {
104 lazy_static! {
105 static ref DRAFT7: Value = serde_json::from_str(include_str!("draft7.json")).unwrap();
106 }
107 &DRAFT7
108 }
109
110 pub(super) fn get_format_checker(key: &str) -> Option<FormatChecker> {
111 match key {
112 "date" => Some(format::date as FormatChecker),
113 "date-time" => Some(format::datetime as FormatChecker),
114 "email" => Some(format::email as FormatChecker),
115 "hostname" => Some(format::hostname as FormatChecker),
116 "idn-email" => Some(format::email as FormatChecker),
117 "ipv4" => Some(format::ipv4 as FormatChecker),
118 "ipv6" => Some(format::ipv6 as FormatChecker),
119 "iri" => Some(format::iri as FormatChecker),
120 "iri-reference" => Some(format::iri_reference as FormatChecker),
121 "json-pointer" => Some(format::json_pointer as FormatChecker),
122 "regex" => Some(format::regex as FormatChecker),
123 "time" => Some(format::time as FormatChecker),
124 "uri" => Some(format::uri as FormatChecker),
125 "uri-reference" => Some(format::uri_reference as FormatChecker),
126 "uri-template" => Some(format::uri_template as FormatChecker),
127 _ => None,
128 }
129 }
130}
131
132mod draft6 {
133 use super::*;
134
135 pub(super) fn get_validator(key: &str) -> Option<Validator> {
136 match key {
137 "$ref" => Some(validators::ref_ as Validator),
138 "additionalItems" => Some(validators::additionalItems as Validator),
139 "additionalProperties" => Some(validators::additionalProperties as Validator),
140 "allOf" => Some(validators::allOf as Validator),
141 "anyOf" => Some(validators::anyOf as Validator),
142 "const" => Some(validators::const_ as Validator),
143 "contains" => Some(validators::contains as Validator),
144 "dependencies" => Some(validators::dependencies as Validator),
145 "enum" => Some(validators::enum_ as Validator),
146 "exclusiveMaximum" => Some(validators::exclusiveMaximum as Validator),
147 "exclusiveMinimum" => Some(validators::exclusiveMinimum as Validator),
148 "format" => Some(validators::format as Validator),
149 "items" => Some(validators::items as Validator),
150 "maxItems" => Some(validators::maxItems as Validator),
151 "maxLength" => Some(validators::maxLength as Validator),
152 "maxProperties" => Some(validators::maxProperties as Validator),
153 "maximum" => Some(validators::maximum as Validator),
154 "minItems" => Some(validators::minItems as Validator),
155 "minLength" => Some(validators::minLength as Validator),
156 "minProperties" => Some(validators::minProperties as Validator),
157 "minimum" => Some(validators::minimum as Validator),
158 "multipleOf" => Some(validators::multipleOf as Validator),
159 "not" => Some(validators::not as Validator),
160 "oneOf" => Some(validators::oneOf as Validator),
161 "pattern" => Some(validators::pattern as Validator),
162 "patternProperties" => Some(validators::patternProperties as Validator),
163 "properties" => Some(validators::properties as Validator),
164 "propertyNames" => Some(validators::propertyNames as Validator),
165 "required" => Some(validators::required as Validator),
166 "type" => Some(validators::type_ as Validator),
167 "uniqueItems" => Some(validators::uniqueItems as Validator),
168 _ => None,
169 }
170 }
171
172 pub(super) fn get_schema() -> &'static Value {
173 lazy_static! {
174 static ref DRAFT6: Value = serde_json::from_str(include_str!("draft6.json")).unwrap();
175 }
176 &DRAFT6
177 }
178
179 pub(super) fn get_format_checker(key: &str) -> Option<FormatChecker> {
180 match key {
181 "date" => Some(format::date as FormatChecker),
182 "date-time" => Some(format::datetime as FormatChecker),
183 "email" => Some(format::email as FormatChecker),
184 "hostname" => Some(format::hostname as FormatChecker),
185 "ipv4" => Some(format::ipv4 as FormatChecker),
186 "ipv6" => Some(format::ipv6 as FormatChecker),
187 "json-pointer" => Some(format::json_pointer as FormatChecker),
188 "regex" => Some(format::regex as FormatChecker),
189 "time" => Some(format::time as FormatChecker),
190 "uri" => Some(format::uri as FormatChecker),
191 "uri-reference" => Some(format::uri_reference as FormatChecker),
192 "uri-template" => Some(format::uri_template as FormatChecker),
193 _ => None,
194 }
195 }
196}
197
198mod draft4 {
199 use super::*;
200
201 pub(super) fn get_validator(key: &str) -> Option<Validator> {
202 match key {
203 "$ref" => Some(validators::ref_ as Validator),
204 "additionalItems" => Some(validators::additionalItems as Validator),
205 "additionalProperties" => Some(validators::additionalProperties as Validator),
206 "allOf" => Some(validators::allOf as Validator),
207 "anyOf" => Some(validators::anyOf as Validator),
208 "dependencies" => Some(validators::dependencies as Validator),
209 "enum" => Some(validators::enum_ as Validator),
210 "format" => Some(validators::format as Validator),
211 "items" => Some(validators::items as Validator),
212 "maxItems" => Some(validators::maxItems as Validator),
213 "maxLength" => Some(validators::maxLength as Validator),
214 "maxProperties" => Some(validators::maxProperties as Validator),
215 "maximum" => Some(validators::maximum_draft4 as Validator),
216 "minItems" => Some(validators::minItems as Validator),
217 "minLength" => Some(validators::minLength as Validator),
218 "minProperties" => Some(validators::minProperties as Validator),
219 "minimum" => Some(validators::minimum_draft4 as Validator),
220 "multipleOf" => Some(validators::multipleOf as Validator),
221 "not" => Some(validators::not as Validator),
222 "oneOf" => Some(validators::oneOf as Validator),
223 "pattern" => Some(validators::pattern as Validator),
224 "patternProperties" => Some(validators::patternProperties as Validator),
225 "properties" => Some(validators::properties as Validator),
226 "required" => Some(validators::required as Validator),
227 "type" => Some(validators::type_ as Validator),
228 "uniqueItems" => Some(validators::uniqueItems as Validator),
229 _ => None,
230 }
231 }
232
233 pub(super) fn get_schema() -> &'static Value {
234 lazy_static! {
235 static ref DRAFT4: Value = serde_json::from_str(include_str!("draft4.json")).unwrap();
236 }
237 &DRAFT4
238 }
239
240 pub(super) fn get_format_checker(key: &str) -> Option<FormatChecker> {
241 match key {
242 "date-time" => Some(format::datetime as FormatChecker),
243 "email" => Some(format::email as FormatChecker),
244 "hostname" => Some(format::hostname as FormatChecker),
245 "ipv4" => Some(format::ipv4 as FormatChecker),
246 "ipv6" => Some(format::ipv6 as FormatChecker),
247 "regex" => Some(format::regex as FormatChecker),
248 "uri" => Some(format::uri as FormatChecker),
249 _ => None,
250 }
251 }
252}
253
254pub fn draft_from_url(url: &str) -> Option<Draft> {
256 match url {
257 "http://json-schema.org/draft-07/schema" => Some(Draft::Draft7),
258 "http://json-schema.org/draft-06/schema" => Some(Draft::Draft6),
259 "http://json-schema.org/draft-04/schema" => Some(Draft::Draft4),
260 _ => None,
261 }
262}
263
264pub fn draft_from_schema(schema: &Value) -> Option<Draft> {
266 schema
267 .as_object()
268 .and_then(|x| x.get("$schema"))
269 .and_then(Value::as_str)
270 .and_then(draft_from_url)
271}