diff --git a/typify-impl/src/defaults.rs b/typify-impl/src/defaults.rs
index 658b2185..6a343575 100644
--- a/typify-impl/src/defaults.rs
+++ b/typify-impl/src/defaults.rs
@@ -137,7 +137,8 @@ impl TypeEntry {
/// The return value indicates whether the default is the "intrinsic",
/// typical default for the given type, can be handled by generic function,
/// or requires a bespoke function to generate the value. This contains
- /// additional validation logic compared with [`value()`] but is able to skip the parts where we actually emit code.
+ /// additional validation logic compared with [`value()`] but is able to
+ /// skip the parts where we actually emit code.
///
/// [`Value`]: serde_json::Value
pub(crate) fn validate_value(
@@ -172,7 +173,11 @@ impl TypeEntry {
}
TypeEntryDetails::Newtype(TypeEntryNewtype { type_id, .. }) => {
- validate_type_id(type_id, type_space, default)
+ // Validate the inner type, but irrespective of the result,
+ // we'll need a custom function to make a default of the outer
+ // newtype.
+ let _ = validate_type_id(type_id, type_space, default)?;
+ Ok(DefaultKind::Specific)
}
TypeEntryDetails::Option(type_id) => {
if let serde_json::Value::Null = default {
diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs
index a10b2afe..a9cf8c24 100644
--- a/typify-impl/src/lib.rs
+++ b/typify-impl/src/lib.rs
@@ -7,7 +7,7 @@
use std::collections::{BTreeMap, BTreeSet};
use conversions::SchemaCache;
-use log::info;
+use log::{debug, info};
use output::OutputSpace;
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
@@ -696,6 +696,7 @@ impl TypeSpace {
for index in base_id..self.next_id {
let type_id = TypeId(index);
let mut type_entry = self.id_to_entry.get(&type_id).unwrap().clone();
+ debug!("finalizing type entry: {} {:#?}", index, &type_entry);
type_entry.finalize(self)?;
self.id_to_entry.insert(type_id, type_entry);
}
diff --git a/typify/tests/schemas/types-with-defaults.json b/typify/tests/schemas/types-with-defaults.json
index fb7c714e..f3666710 100644
--- a/typify/tests/schemas/types-with-defaults.json
+++ b/typify/tests/schemas/types-with-defaults.json
@@ -85,6 +85,22 @@
"default": 1
}
}
+ },
+ "UInt": {
+ "type": "integer"
+ },
+ "UIntContainer": {
+ "type": "object",
+ "properties": {
+ "max_path": {
+ "default": 1,
+ "allOf": [
+ {
+ "$ref": "#/$definitions/UInt"
+ }
+ ]
+ }
+ }
}
}
}
diff --git a/typify/tests/schemas/types-with-defaults.rs b/typify/tests/schemas/types-with-defaults.rs
index 8e5b0843..383ece76 100644
--- a/typify/tests/schemas/types-with-defaults.rs
+++ b/typify/tests/schemas/types-with-defaults.rs
@@ -262,6 +262,95 @@ impl ThingWithDefaults {
Default::default()
}
}
+#[doc = "`UInt`"]
+#[doc = r""]
+#[doc = r" JSON schema
"]
+#[doc = r""]
+#[doc = r" ```json"]
+#[doc = "{"]
+#[doc = " \"type\": \"integer\""]
+#[doc = "}"]
+#[doc = r" ```"]
+#[doc = r" "]
+#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)]
+#[serde(transparent)]
+pub struct UInt(pub i64);
+impl ::std::ops::Deref for UInt {
+ type Target = i64;
+ fn deref(&self) -> &i64 {
+ &self.0
+ }
+}
+impl ::std::convert::From for i64 {
+ fn from(value: UInt) -> Self {
+ value.0
+ }
+}
+impl ::std::convert::From for UInt {
+ fn from(value: i64) -> Self {
+ Self(value)
+ }
+}
+impl ::std::str::FromStr for UInt {
+ type Err = ::Err;
+ fn from_str(value: &str) -> ::std::result::Result {
+ Ok(Self(value.parse()?))
+ }
+}
+impl ::std::convert::TryFrom<&str> for UInt {
+ type Error = ::Err;
+ fn try_from(value: &str) -> ::std::result::Result {
+ value.parse()
+ }
+}
+impl ::std::convert::TryFrom for UInt {
+ type Error = ::Err;
+ fn try_from(value: String) -> ::std::result::Result {
+ value.parse()
+ }
+}
+impl ::std::fmt::Display for UInt {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ self.0.fmt(f)
+ }
+}
+#[doc = "`UIntContainer`"]
+#[doc = r""]
+#[doc = r" JSON schema
"]
+#[doc = r""]
+#[doc = r" ```json"]
+#[doc = "{"]
+#[doc = " \"type\": \"object\","]
+#[doc = " \"properties\": {"]
+#[doc = " \"max_path\": {"]
+#[doc = " \"default\": 1,"]
+#[doc = " \"allOf\": ["]
+#[doc = " {"]
+#[doc = " \"$ref\": \"#/$definitions/UInt\""]
+#[doc = " }"]
+#[doc = " ]"]
+#[doc = " }"]
+#[doc = " }"]
+#[doc = "}"]
+#[doc = r" ```"]
+#[doc = r" "]
+#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)]
+pub struct UIntContainer {
+ #[serde(default = "defaults::u_int_container_max_path")]
+ pub max_path: UInt,
+}
+impl ::std::default::Default for UIntContainer {
+ fn default() -> Self {
+ Self {
+ max_path: defaults::u_int_container_max_path(),
+ }
+ }
+}
+impl UIntContainer {
+ pub fn builder() -> builder::UIntContainer {
+ Default::default()
+ }
+}
#[doc = r" Types for composing complex structures."]
pub mod builder {
#[derive(Clone, Debug)]
@@ -527,6 +616,46 @@ pub mod builder {
}
}
}
+ #[derive(Clone, Debug)]
+ pub struct UIntContainer {
+ max_path: ::std::result::Result,
+ }
+ impl ::std::default::Default for UIntContainer {
+ fn default() -> Self {
+ Self {
+ max_path: Ok(super::defaults::u_int_container_max_path()),
+ }
+ }
+ }
+ impl UIntContainer {
+ pub fn max_path(mut self, value: T) -> Self
+ where
+ T: ::std::convert::TryInto,
+ T::Error: ::std::fmt::Display,
+ {
+ self.max_path = value
+ .try_into()
+ .map_err(|e| format!("error converting supplied value for max_path: {e}"));
+ self
+ }
+ }
+ impl ::std::convert::TryFrom for super::UIntContainer {
+ type Error = super::error::ConversionError;
+ fn try_from(
+ value: UIntContainer,
+ ) -> ::std::result::Result {
+ Ok(Self {
+ max_path: value.max_path?,
+ })
+ }
+ }
+ impl ::std::convert::From for UIntContainer {
+ fn from(value: super::UIntContainer) -> Self {
+ Self {
+ max_path: Ok(value.max_path),
+ }
+ }
+ }
}
#[doc = r" Generation of default values for serde."]
pub mod defaults {
@@ -556,5 +685,8 @@ pub mod defaults {
pub(super) fn test_bed_id() -> ::uuid::Uuid {
::serde_json::from_str::<::uuid::Uuid>("\"abc123-is-this-a-uuid\"").unwrap()
}
+ pub(super) fn u_int_container_max_path() -> super::UInt {
+ super::UInt(1_i64)
+ }
}
fn main() {}