diff --git a/src/json_schema/mod.rs b/src/json_schema/mod.rs index 45234622..d18f5f5f 100644 --- a/src/json_schema/mod.rs +++ b/src/json_schema/mod.rs @@ -82,3 +82,66 @@ pub fn to_regex( _ => Err(anyhow!("Invalid JSON Schema: expected an object")), } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn error_on_recursive_ref() { + let json = r##" + { + "type": "object", + "properties": { + "name": { "type": "string" }, + "children": { + "type": "array", + "items": { "$ref": "#" } + } + } + }"##; + + let json_value: Value = serde_json::from_str(json).expect("Can't parse json"); + let result = to_regex(&json_value, None, &json_value); + + match result { + Err(e) => { + let message = "Recursive references are not supported for now"; + assert_eq!(message, e.to_string()); + } + _ => unreachable!(), + } + } + + #[test] + fn internal_ref_works() { + let json = r##" + { + "definitions": { + "address": { + "type": "object", + "properties": { + "street": { "type": "string" }, + "city": { "type": "string" } + } + } + }, + "type": "object", + "properties": { + "home_address": { "$ref": "#/definitions/address" }, + "work_address": { "$ref": "#/definitions/address" } + } + }"##; + + let json_value: Value = serde_json::from_str(json).expect("Can't parse json"); + let result = to_regex(&json_value, None, &json_value); + + match result { + Ok(r) => { + assert!(r.contains("home_address")); + assert!(r.contains("work_address")); + } + _ => unreachable!(), + } + } +} diff --git a/src/json_schema/parsing.rs b/src/json_schema/parsing.rs index be6e253a..4182ac8e 100644 --- a/src/json_schema/parsing.rs +++ b/src/json_schema/parsing.rs @@ -239,6 +239,10 @@ pub fn parse_ref( .as_str() .ok_or_else(|| anyhow!("'$ref' must be a string"))?; + if ref_path == "#" { + return Err(anyhow!("Recursive references are not supported for now")); + } + let parts: Vec<&str> = ref_path.split('#').collect(); match parts.as_slice() {