From ba192714a17a7663dca3cfaf03cb8394397c5043 Mon Sep 17 00:00:00 2001 From: Erik Holman Date: Thu, 19 Mar 2026 13:24:41 +0100 Subject: [PATCH] Support $ref generation --- src/json_schema.rs | 9 +++++++-- src/lib.rs | 14 ++++++++++++++ src/schema.rs | 13 +++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/json_schema.rs b/src/json_schema.rs index 348aa94..d0fb9f7 100644 --- a/src/json_schema.rs +++ b/src/json_schema.rs @@ -247,8 +247,13 @@ where F: Fn(&serde_json::Value) -> Result, { fn json_schema(&self) -> Value { - // Nested schemas are opaque closures; emit a generic object schema. - serde_json::json!({"type": "object"}) + match self.name { + Some(name) => serde_json::json!({ + "$ref": format!("#/components/schemas/{}", name) + }), + // Nested schemas are opaque closures; emit a generic object schema + None => serde_json::json!({ "type": "object" }), + } } } diff --git a/src/lib.rs b/src/lib.rs index 8de7778..577b63a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,6 +135,20 @@ where schema::NestedSchema::new(f) } +pub fn nested_named(name: &'static str, f: F) -> schema::NestedSchema +where + F: Fn(&serde_json::Value) -> Result, +{ + schema::NestedSchema::new_named(f, name) +} + +#[macro_export] +macro_rules! nested { + ($ty:ty) => { + $crate::nested_named(stringify!($ty), <$ty>::parse_value) + }; +} + /// Create a literal value schema. Validates exact match. /// /// ``` diff --git a/src/schema.rs b/src/schema.rs index 5e73231..57c9a96 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -199,6 +199,7 @@ where F: Fn(&Value) -> Result, { parse_fn: F, + pub(crate) name: Option<&'static str>, _phantom: PhantomData, } @@ -209,6 +210,15 @@ where pub fn new(f: F) -> Self { Self { parse_fn: f, + name: None, + _phantom: PhantomData, + } + } + + pub fn new_named(f: F, name: &'static str) -> Self { + Self { + parse_fn: f, + name: Some(name), _phantom: PhantomData, } } @@ -219,8 +229,7 @@ where F: Fn(&Value) -> Result, { type Output = T; - fn parse_value(&self, value: &Value) -> Result { (self.parse_fn)(value) } -} +} \ No newline at end of file