diff --git a/parser/src/json/schema.rs b/parser/src/json/schema.rs index 06ba72f..0c94edb 100644 --- a/parser/src/json/schema.rs +++ b/parser/src/json/schema.rs @@ -15,7 +15,7 @@ const DEFAULT_DRAFT: Draft = Draft::Draft202012; const TYPES: [&str; 6] = ["null", "boolean", "number", "string", "array", "object"]; // Keywords that are implemented in this module -const IMPLEMENTED: [&str; 22] = [ +const IMPLEMENTED: [&str; 23] = [ // Core "anyOf", "oneOf", @@ -26,6 +26,7 @@ const IMPLEMENTED: [&str; 22] = [ "type", // Array "items", + "additionalItems", "prefixItems", "minItems", "maxItems", @@ -611,6 +612,7 @@ fn compile_type(ctx: &Context, tp: &str, schema: &HashMap<&str, &Value>) -> Resu get("maxItems"), get("prefixItems"), get("items"), + get("additionalItems"), ), "object" => compile_object( ctx, @@ -726,7 +728,22 @@ fn compile_array( max_items: Option<&Value>, prefix_items: Option<&Value>, items: Option<&Value>, + additional_items: Option<&Value>, ) -> Result { + let (prefix_items, items) = { + // Note that draft detection falls back to Draft202012 if the draft is unknown, so let's relax the draft constraint a bit + // and assume we're in an old draft if additionalItems is present or items is an array + if ctx.draft <= Draft::Draft201909 || additional_items.is_some() || matches!(items, Some(Value::Array(..))) { + match (items, additional_items) { + // Treat array items as prefixItems and additionalItems as items in draft 2019-09 and earlier + (Some(Value::Array(..)), _) => (items, additional_items), + // items is treated as items, and additionalItems is ignored if items is not an array (or is missing) + _ => (None, items), + } + } else { + (prefix_items, items) + } + }; let min_items = match min_items { None => 0, Some(val) => val