json_schema_tools/
lint.rs1use super::schema::SchemaFile;
2use serde_json::Value;
3
4#[derive(Debug)]
5pub enum Issue<'a> {
6 Json(serde_json::Error),
7 MisorderedKeys(super::key_order::KeyOrderMismatch<'a>),
8 UnrestrictedProperties(Vec<String>),
9 OptionalField(Vec<String>, String),
10 MisorderedRequires(Vec<String>),
11}
12
13pub fn lint(schema_file_value: &Value) -> Vec<Issue> {
14 let mut result = vec![];
15
16 for key_order_mismatch in super::key_order::check_key_order(schema_file_value) {
17 result.push(Issue::MisorderedKeys(key_order_mismatch));
18 }
19
20 match serde_json::from_value::<SchemaFile>(schema_file_value.clone()) {
21 Ok(schema_file) => {
22 for (path, object) in schema_file.objects() {
23 if !object.no_additional_properties() {
24 result.push(Issue::UnrestrictedProperties(path.clone()));
25 }
26
27 let mut optional_fields = object.properties.keys().collect::<Vec<_>>();
28 optional_fields.retain(|value| !object.required.contains(value));
29
30 for optional_field in optional_fields {
31 result.push(Issue::OptionalField(path.clone(), optional_field.clone()));
32 }
33
34 let mut required_fields = object.properties.keys().collect::<Vec<_>>();
35 required_fields.retain(|value| object.required.contains(value));
36
37 if required_fields != object.required.iter().collect::<Vec<_>>() {
38 result.push(Issue::MisorderedRequires(path.clone()));
39 }
40 }
41 }
42 Err(error) => {
43 result.push(Issue::Json(error));
44 }
45 }
46
47 result
48}