From c2e2c7395f83aa70096dcf0d983d287ad87bf4d7 Mon Sep 17 00:00:00 2001 From: ericszentivanyi <247076009+ericszentivanyi@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:39:10 -0500 Subject: [PATCH 1/5] fix!: require title when there are no definitions in the schema --- typify-impl/src/lib.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs index 2f791ba2..f13ea5c3 100644 --- a/typify-impl/src/lib.rs +++ b/typify-impl/src/lib.rs @@ -46,7 +46,7 @@ pub enum Error { InvalidTypeId, #[error("value does not conform to the given schema")] InvalidValue, - #[error("invalid schema for {}: {reason}", show_type_name(.type_name.as_deref()))] + #[error("invalid schema{}: {reason}", show_type_name(.type_name.as_deref()))] InvalidSchema { type_name: Option, reason: String, @@ -62,8 +62,11 @@ impl Error { #[allow(missing_docs)] pub type Result = std::result::Result; -fn show_type_name(type_name: Option<&str>) -> &str { - type_name.unwrap_or("") +fn show_type_name(type_name: Option<&str>) -> String { + match type_name { + Some(name) => format!(" for {}", name), + None => String::new(), + } } /// Representation of a type which may have a definition or may be built-in. @@ -790,6 +793,20 @@ impl TypeSpace { definitions, } = schema; + if definitions.is_empty() { + if schema + .metadata + .as_ref() + .and_then(|m| m.title.as_ref()) + .is_none() + { + return Err(Error::InvalidSchema { + type_name: None, + reason: "title is required when there are no definitions".to_string(), + }); + } + } + let mut defs = definitions .into_iter() .map(|(key, schema)| (RefKey::Def(key), schema)) From 843da7462fee04a26780a55865001c343c9d7319 Mon Sep 17 00:00:00 2001 From: ericszentivanyi <247076009+ericszentivanyi@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:41:03 -0500 Subject: [PATCH 2/5] chore: rename `show_type_name` --- typify-impl/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs index f13ea5c3..6486cade 100644 --- a/typify-impl/src/lib.rs +++ b/typify-impl/src/lib.rs @@ -46,7 +46,7 @@ pub enum Error { InvalidTypeId, #[error("value does not conform to the given schema")] InvalidValue, - #[error("invalid schema{}: {reason}", show_type_name(.type_name.as_deref()))] + #[error("invalid schema{}: {reason}", format_type_name(.type_name.as_deref()))] InvalidSchema { type_name: Option, reason: String, @@ -62,7 +62,7 @@ impl Error { #[allow(missing_docs)] pub type Result = std::result::Result; -fn show_type_name(type_name: Option<&str>) -> String { +fn format_type_name(type_name: Option<&str>) -> String { match type_name { Some(name) => format!(" for {}", name), None => String::new(), From 7edf8106b65f9bbb7e06890ca79127b94f689429 Mon Sep 17 00:00:00 2001 From: ericszentivanyi <247076009+ericszentivanyi@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:13:31 -0500 Subject: [PATCH 3/5] chore: introduce `InvalidRootSchema` error --- typify-impl/src/lib.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs index 6486cade..2b89b21a 100644 --- a/typify-impl/src/lib.rs +++ b/typify-impl/src/lib.rs @@ -46,11 +46,13 @@ pub enum Error { InvalidTypeId, #[error("value does not conform to the given schema")] InvalidValue, - #[error("invalid schema{}: {reason}", format_type_name(.type_name.as_deref()))] + #[error("invalid schema for {}: {reason}", show_type_name(.type_name.as_deref()))] InvalidSchema { type_name: Option, reason: String, }, + #[error("invalid root schema: {reason}")] + InvalidRootSchema { reason: String }, } impl Error { @@ -62,11 +64,8 @@ impl Error { #[allow(missing_docs)] pub type Result = std::result::Result; -fn format_type_name(type_name: Option<&str>) -> String { - match type_name { - Some(name) => format!(" for {}", name), - None => String::new(), - } +fn show_type_name(type_name: Option<&str>) -> &str { + type_name.unwrap_or("") } /// Representation of a type which may have a definition or may be built-in. @@ -800,8 +799,7 @@ impl TypeSpace { .and_then(|m| m.title.as_ref()) .is_none() { - return Err(Error::InvalidSchema { - type_name: None, + return Err(Error::InvalidRootSchema { reason: "title is required when there are no definitions".to_string(), }); } From 9e665fa6939fc2e0a53d7966ca358983333fbe6d Mon Sep 17 00:00:00 2001 From: ericszentivanyi <247076009+ericszentivanyi@users.noreply.github.com> Date: Wed, 14 Jan 2026 12:29:18 -0500 Subject: [PATCH 4/5] chore: create a `title` variable --- typify-impl/src/lib.rs | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs index 2b89b21a..63c64b7f 100644 --- a/typify-impl/src/lib.rs +++ b/typify-impl/src/lib.rs @@ -792,17 +792,12 @@ impl TypeSpace { definitions, } = schema; - if definitions.is_empty() { - if schema - .metadata - .as_ref() - .and_then(|m| m.title.as_ref()) - .is_none() - { - return Err(Error::InvalidRootSchema { - reason: "title is required when there are no definitions".to_string(), - }); - } + let title = schema.metadata.as_ref().and_then(|m| m.title.as_ref()); + + if definitions.is_empty() && title.is_none() { + return Err(Error::InvalidRootSchema { + reason: "title is required when there are no definitions".to_string(), + }); } let mut defs = definitions @@ -810,12 +805,7 @@ impl TypeSpace { .map(|(key, schema)| (RefKey::Def(key), schema)) .collect::>(); - // Does the root type have a name (otherwise... ignore it) - let root_type = schema - .metadata - .as_ref() - .and_then(|m| m.title.as_ref()) - .is_some(); + let root_type = title.is_some(); if root_type { defs.push((RefKey::Root, schema.into())); From b9d9ccc0e4b75e3d1473ae5919a86fd986436947 Mon Sep 17 00:00:00 2001 From: ericszentivanyi <247076009+ericszentivanyi@users.noreply.github.com> Date: Wed, 14 Jan 2026 12:30:45 -0500 Subject: [PATCH 5/5] docs: restore comment --- typify-impl/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs index 63c64b7f..d3e4ae51 100644 --- a/typify-impl/src/lib.rs +++ b/typify-impl/src/lib.rs @@ -805,6 +805,7 @@ impl TypeSpace { .map(|(key, schema)| (RefKey::Def(key), schema)) .collect::>(); + // Does the root type have a name (otherwise... ignore it) let root_type = title.is_some(); if root_type {