diff --git a/typify-impl/src/defaults.rs b/typify-impl/src/defaults.rs index 6a343575..12942dd3 100644 --- a/typify-impl/src/defaults.rs +++ b/typify-impl/src/defaults.rs @@ -308,7 +308,7 @@ impl TypeEntry { if value == 0.0 { Ok(DefaultKind::Intrinsic) } else { - Ok(DefaultKind::Generic(DefaultImpl::I64)) + Ok(DefaultKind::Specific) } } else { Err(Error::invalid_value()) @@ -794,6 +794,24 @@ mod tests { )); } + #[test] + fn test_default_float() { + let (type_space, type_id) = get_type::(); + let type_entry = type_space.id_to_entry.get(&type_id).unwrap(); + + assert!(type_entry + .validate_value(&type_space, &json!(true)) + .is_err()); + assert!(matches!( + type_entry.validate_value(&type_space, &json!(0.0)), + Ok(DefaultKind::Intrinsic), + )); + assert!(matches!( + type_entry.validate_value(&type_space, &json!(0.1)), + Ok(DefaultKind::Specific), + )); + } + #[test] fn test_struct_simple() { #[derive(JsonSchema)] diff --git a/typify-impl/src/structs.rs b/typify-impl/src/structs.rs index 4e285259..87fbdfb0 100644 --- a/typify-impl/src/structs.rs +++ b/typify-impl/src/structs.rs @@ -461,12 +461,12 @@ fn has_default( } // Default specified is the same as the implicit default: 0 (Some(TypeEntryDetails::Integer(_)), Some(serde_json::Value::Number(n))) - if n.as_u64() == Some(0) => + if n.as_f64() == Some(0.0) => { StructPropertyState::Optional } // Default specified is the same as the implicit default: 0.0 - (Some(TypeEntryDetails::Integer(_)), Some(serde_json::Value::Number(n))) + (Some(TypeEntryDetails::Float(_)), Some(serde_json::Value::Number(n))) if n.as_f64() == Some(0.0) => { StructPropertyState::Optional diff --git a/typify-impl/tests/vega.out b/typify-impl/tests/vega.out index ca8894dc..637366b8 100644 --- a/typify-impl/tests/vega.out +++ b/typify-impl/tests/vega.out @@ -106275,13 +106275,6 @@ pub mod defaults { pub(super) fn default_bool() -> bool { V } - pub(super) fn default_i64() -> T - where - T: ::std::convert::TryFrom, - >::Error: ::std::fmt::Debug, - { - T::try_from(V).unwrap() - } pub(super) fn aggregate_transform_drop() -> super::AggregateTransformDrop { super::AggregateTransformDrop::Boolean(true) } diff --git a/typify/tests/schemas/types-with-defaults.json b/typify/tests/schemas/types-with-defaults.json index f3666710..25ec3054 100644 --- a/typify/tests/schemas/types-with-defaults.json +++ b/typify/tests/schemas/types-with-defaults.json @@ -86,6 +86,19 @@ } } }, + "MrDefaultFloats": { + "type": "object", + "properties": { + "frequency": { + "type": "number", + "default": 0.1 + }, + "zfreq": { + "type": "number", + "default": 0.0 + } + } + }, "UInt": { "type": "integer" }, diff --git a/typify/tests/schemas/types-with-defaults.rs b/typify/tests/schemas/types-with-defaults.rs index 383ece76..60ab284b 100644 --- a/typify/tests/schemas/types-with-defaults.rs +++ b/typify/tests/schemas/types-with-defaults.rs @@ -59,6 +59,46 @@ impl Doodad { Default::default() } } +#[doc = "`MrDefaultFloats`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"properties\": {"] +#[doc = " \"frequency\": {"] +#[doc = " \"default\": 0.1,"] +#[doc = " \"type\": \"number\""] +#[doc = " },"] +#[doc = " \"zfreq\": {"] +#[doc = " \"default\": 0.0,"] +#[doc = " \"type\": \"number\""] +#[doc = " }"] +#[doc = " }"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)] +pub struct MrDefaultFloats { + #[serde(default = "defaults::mr_default_floats_frequency")] + pub frequency: f64, + #[serde(default)] + pub zfreq: f64, +} +impl ::std::default::Default for MrDefaultFloats { + fn default() -> Self { + Self { + frequency: defaults::mr_default_floats_frequency(), + zfreq: Default::default(), + } + } +} +impl MrDefaultFloats { + pub fn builder() -> builder::MrDefaultFloats { + Default::default() + } +} #[doc = "`MrDefaultNumbers`"] #[doc = r""] #[doc = r"
JSON schema"] @@ -391,6 +431,60 @@ pub mod builder { } } #[derive(Clone, Debug)] + pub struct MrDefaultFloats { + frequency: ::std::result::Result, + zfreq: ::std::result::Result, + } + impl ::std::default::Default for MrDefaultFloats { + fn default() -> Self { + Self { + frequency: Ok(super::defaults::mr_default_floats_frequency()), + zfreq: Ok(Default::default()), + } + } + } + impl MrDefaultFloats { + pub fn frequency(mut self, value: T) -> Self + where + T: ::std::convert::TryInto, + T::Error: ::std::fmt::Display, + { + self.frequency = value + .try_into() + .map_err(|e| format!("error converting supplied value for frequency: {e}")); + self + } + pub fn zfreq(mut self, value: T) -> Self + where + T: ::std::convert::TryInto, + T::Error: ::std::fmt::Display, + { + self.zfreq = value + .try_into() + .map_err(|e| format!("error converting supplied value for zfreq: {e}")); + self + } + } + impl ::std::convert::TryFrom for super::MrDefaultFloats { + type Error = super::error::ConversionError; + fn try_from( + value: MrDefaultFloats, + ) -> ::std::result::Result { + Ok(Self { + frequency: value.frequency?, + zfreq: value.zfreq?, + }) + } + } + impl ::std::convert::From for MrDefaultFloats { + fn from(value: super::MrDefaultFloats) -> Self { + Self { + frequency: Ok(value.frequency), + zfreq: Ok(value.zfreq), + } + } + } + #[derive(Clone, Debug)] pub struct MrDefaultNumbers { big_nullable: ::std::result::Result< ::std::option::Option<::std::num::NonZeroU64>, @@ -672,6 +766,9 @@ pub mod defaults { ) .unwrap() } + pub(super) fn mr_default_floats_frequency() -> f64 { + 0.1_f64 + } pub(super) fn mr_default_numbers_big_nullable() -> ::std::option::Option<::std::num::NonZeroU64> { ::std::option::Option::Some(::std::num::NonZeroU64::new(1).unwrap())