diff --git a/typify-impl/src/type_entry.rs b/typify-impl/src/type_entry.rs index b79a42c8..be2ee246 100644 --- a/typify-impl/src/type_entry.rs +++ b/typify-impl/src/type_entry.rs @@ -1355,12 +1355,12 @@ impl TypeEntry { } } - fn output_newtype( + fn output_newtype<'a>( &self, - type_space: &TypeSpace, + type_space: &'a TypeSpace, output: &mut OutputSpace, newtype_details: &TypeEntryNewtype, - mut derive_set: BTreeSet<&str>, + mut derive_set: BTreeSet<&'a str>, ) { let TypeEntryNewtype { name, @@ -1385,6 +1385,8 @@ impl TypeEntry { derive_set.extend(["PartialOrd", "Ord", "PartialEq", "Eq", "Hash"]); } + derive_set.extend(type_space.settings.extra_derives.iter().map(|s| s.as_str())); + let constraint_impl = match constraints { // In the unconstrained case we proxy impls through the inner type. TypeEntryNewtypeConstraints::None => { @@ -1467,8 +1469,6 @@ impl TypeEntry { TypeEntryNewtypeConstraints::DenyValue(enum_values) | TypeEntryNewtypeConstraints::EnumValue(enum_values) => { - let not = matches!(constraints, TypeEntryNewtypeConstraints::EnumValue(_)) - .then(|| quote! { ! }); // Note that string types with enumerated values are converted // into simple enums rather than newtypes so we would not // expect to see a string as the inner type here. @@ -1481,15 +1481,75 @@ impl TypeEntry { // from the set of derived impls. derive_set.remove("::serde::Deserialize"); - // TODO: if a user were to derive schemars::JsonSchema, it - // wouldn't be accurate. - let value_output = enum_values .iter() .map(|value| inner_type.output_value(type_space, &value.0, "e! {})); + + let value_string = enum_values + .iter() + .map(|value| serde_json::to_string(&value.0).unwrap()); + + // As with Deserialize, serde::JsonSchema requires a custom + // impl. If it's present in the set of derives, remove it and + // generate something that accurately models the type. + + let has_json_schema = derive_set.remove("schemars::JsonSchema") + || derive_set.remove("::schemars::JsonSchema"); + let json_schema = has_json_schema.then(|| match constraints { + TypeEntryNewtypeConstraints::DenyValue(_) => quote! { + impl ::schemars::JsonSchema for #type_name { + fn schema_name() -> ::std::string::String { + #name.to_string() + } + + fn json_schema(gen: &mut ::schemars::gen::SchemaGenerator) + -> ::schemars::schema::Schema { + let mut schema = + <#inner_type_name as ::schemars::JsonSchema> + ::json_schema(gen) + .into_object(); + let not = ::schemars::schema::SchemaObject { + enum_values: ::std::option::Option::Some([ + #( ::serde_json::from_str(#value_string).unwrap(), )* + ].into_iter().collect()), + ..::std::default::Default::default() + }; + schema.subschemas().not = Some( + ::std::boxed::Box::new(not.into()) + ); + schema.into() + } + } + }, + TypeEntryNewtypeConstraints::EnumValue(_) => quote! { + impl ::schemars::JsonSchema for #type_name { + fn schema_name() -> ::std::string::String { + #name.to_string() + } + + fn json_schema(gen: &mut ::schemars::gen::SchemaGenerator) + -> ::schemars::schema::Schema { + let mut schema = + <#inner_type_name as ::schemars::JsonSchema> + ::json_schema(gen) + .into_object(); + schema.enum_values = ::std::option::Option::Some([ + #( ::serde_json::from_str(#value_string).unwrap(), )* + ].into_iter().collect()); + schema.into() + } + } + }, + + _ => unreachable!(), + }); + // TODO if the sub_type is a string we could probably impl // TryFrom<&str> as well and FromStr. - // TODO maybe we want to handle JsonSchema here + + let not = matches!(constraints, TypeEntryNewtypeConstraints::EnumValue(_)) + .then(|| quote! { ! }); + quote! { // This is effectively the constructor for this type. impl ::std::convert::TryFrom<#inner_type_name> for #type_name { @@ -1526,6 +1586,8 @@ impl TypeEntry { }) } } + + #json_schema } } @@ -1648,11 +1710,10 @@ impl TypeEntry { } }); - let derives = strings_to_derives( - derive_set, - &self.extra_derives, - &type_space.settings.extra_derives, - ); + // This isn't the cleanest. Unlike other types, we roll in the + // extra_derives here so that we can sniff out and override uses of + // "schemars::JsonSchema". + let derives = strings_to_derives(derive_set, &self.extra_derives, &[]); let attrs = strings_to_attrs(&self.extra_attrs, &type_space.settings.extra_attrs); diff --git a/typify/tests/schemas.rs b/typify/tests/schemas.rs index ad01b014..6de0051b 100644 --- a/typify/tests/schemas.rs +++ b/typify/tests/schemas.rs @@ -37,6 +37,20 @@ fn test_custom_map() { trybuild::TestCases::new().pass("tests/schemas/maps_custom.rs"); } +/// Ensure that enumerated types include the enumeration in their JsonSchema +/// implementation. +#[test] +fn test_various_enums_json_schema() { + validate_schema( + "tests/schemas/various-enums.json".into(), + "tests/schemas/various-enums-json-schema.rs".into(), + TypeSpaceSettings::default().with_derive("schemars::JsonSchema".to_string()), + ) + .unwrap(); + + trybuild::TestCases::new().pass("tests/schemas/various-enums-json-schema.rs"); +} + fn validate_schema( path: std::path::PathBuf, out_path: std::path::PathBuf, diff --git a/typify/tests/schemas/various-enums-json-schema.rs b/typify/tests/schemas/various-enums-json-schema.rs new file mode 100644 index 00000000..9add93c7 --- /dev/null +++ b/typify/tests/schemas/various-enums-json-schema.rs @@ -0,0 +1,1953 @@ +#![deny(warnings)] +#[doc = r" Error types."] +pub mod error { + #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] + pub struct ConversionError(::std::borrow::Cow<'static, str>); + impl ::std::error::Error for ConversionError {} + impl ::std::fmt::Display for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Display::fmt(&self.0, f) + } + } + impl ::std::fmt::Debug for ConversionError { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { + ::std::fmt::Debug::fmt(&self.0, f) + } + } + impl From<&'static str> for ConversionError { + fn from(value: &'static str) -> Self { + Self(value.into()) + } + } + impl From for ConversionError { + fn from(value: String) -> Self { + Self(value.into()) + } + } +} +#[doc = "`AlternativeEnum`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"default\": \"Choice2\","] +#[doc = " \"type\": \"string\","] +#[doc = " \"enum\": ["] +#[doc = " \"Choice1\","] +#[doc = " \"Choice2\","] +#[doc = " \"Choice3\""] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +pub enum AlternativeEnum { + Choice1, + Choice2, + Choice3, +} +impl ::std::fmt::Display for AlternativeEnum { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match *self { + Self::Choice1 => f.write_str("Choice1"), + Self::Choice2 => f.write_str("Choice2"), + Self::Choice3 => f.write_str("Choice3"), + } + } +} +impl ::std::str::FromStr for AlternativeEnum { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + match value { + "Choice1" => Ok(Self::Choice1), + "Choice2" => Ok(Self::Choice2), + "Choice3" => Ok(Self::Choice3), + _ => Err("invalid value".into()), + } + } +} +impl ::std::convert::TryFrom<&str> for AlternativeEnum { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for AlternativeEnum { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for AlternativeEnum { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::default::Default for AlternativeEnum { + fn default() -> Self { + AlternativeEnum::Choice2 + } +} +#[doc = "`AnyOfNoStrings`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"string\","] +#[doc = " \"enum\": []"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(deny_unknown_fields)] +pub enum AnyOfNoStrings {} +#[doc = "`AnyOfNothing`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"enum\": []"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(deny_unknown_fields)] +pub enum AnyOfNothing {} +#[doc = "`BlockSize`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"integer\","] +#[doc = " \"enum\": ["] +#[doc = " 512,"] +#[doc = " 2048,"] +#[doc = " 4096"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Serialize, Clone, Debug)] +#[serde(transparent)] +pub struct BlockSize(i64); +impl ::std::ops::Deref for BlockSize { + type Target = i64; + fn deref(&self) -> &i64 { + &self.0 + } +} +impl ::std::convert::From for i64 { + fn from(value: BlockSize) -> Self { + value.0 + } +} +impl ::std::convert::TryFrom for BlockSize { + type Error = self::error::ConversionError; + fn try_from(value: i64) -> ::std::result::Result { + if ![512_i64, 2048_i64, 4096_i64].contains(&value) { + Err("invalid value".into()) + } else { + Ok(Self(value)) + } + } +} +impl<'de> ::serde::Deserialize<'de> for BlockSize { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + Self::try_from(::deserialize(deserializer)?) + .map_err(|e| ::custom(e.to_string())) + } +} +impl ::schemars::JsonSchema for BlockSize { + fn schema_name() -> ::std::string::String { + "BlockSize".to_string() + } + fn json_schema(gen: &mut ::schemars::gen::SchemaGenerator) -> ::schemars::schema::Schema { + let mut schema = ::json_schema(gen).into_object(); + schema.enum_values = ::std::option::Option::Some( + [ + ::serde_json::from_str("512").unwrap(), + ::serde_json::from_str("2048").unwrap(), + ::serde_json::from_str("4096").unwrap(), + ] + .into_iter() + .collect(), + ); + schema.into() + } +} +#[doc = "`CommentedVariants`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"description\": \"An A\","] +#[doc = " \"enum\": ["] +#[doc = " \"A\""] +#[doc = " ]"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"description\": \"A B\","] +#[doc = " \"enum\": ["] +#[doc = " \"B\""] +#[doc = " ]"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"description\": \"a pirate's favorite letter\","] +#[doc = " \"const\": \"C\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +pub enum CommentedVariants { + #[doc = "An A"] + A, + #[doc = "A B"] + B, + #[doc = "a pirate's favorite letter"] + C, +} +impl ::std::fmt::Display for CommentedVariants { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match *self { + Self::A => f.write_str("A"), + Self::B => f.write_str("B"), + Self::C => f.write_str("C"), + } + } +} +impl ::std::str::FromStr for CommentedVariants { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + match value { + "A" => Ok(Self::A), + "B" => Ok(Self::B), + "C" => Ok(Self::C), + _ => Err("invalid value".into()), + } + } +} +impl ::std::convert::TryFrom<&str> for CommentedVariants { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for CommentedVariants { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for CommentedVariants { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +#[doc = "`DiskAttachment`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"required\": ["] +#[doc = " \"alternate\","] +#[doc = " \"state\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"alternate\": {"] +#[doc = " \"$ref\": \"#/components/schemas/AlternativeEnum\""] +#[doc = " },"] +#[doc = " \"state\": {"] +#[doc = " \"default\": \"Detached\","] +#[doc = " \"type\": \"string\","] +#[doc = " \"enum\": ["] +#[doc = " \"Detached\","] +#[doc = " \"Destroyed\","] +#[doc = " \"Faulted\""] +#[doc = " ]"] +#[doc = " }"] +#[doc = " }"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +pub struct DiskAttachment { + pub alternate: AlternativeEnum, + pub state: DiskAttachmentState, +} +impl DiskAttachment { + pub fn builder() -> builder::DiskAttachment { + Default::default() + } +} +#[doc = "`DiskAttachmentState`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"default\": \"Detached\","] +#[doc = " \"type\": \"string\","] +#[doc = " \"enum\": ["] +#[doc = " \"Detached\","] +#[doc = " \"Destroyed\","] +#[doc = " \"Faulted\""] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +pub enum DiskAttachmentState { + Detached, + Destroyed, + Faulted, +} +impl ::std::fmt::Display for DiskAttachmentState { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match *self { + Self::Detached => f.write_str("Detached"), + Self::Destroyed => f.write_str("Destroyed"), + Self::Faulted => f.write_str("Faulted"), + } + } +} +impl ::std::str::FromStr for DiskAttachmentState { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + match value { + "Detached" => Ok(Self::Detached), + "Destroyed" => Ok(Self::Destroyed), + "Faulted" => Ok(Self::Faulted), + _ => Err("invalid value".into()), + } + } +} +impl ::std::convert::TryFrom<&str> for DiskAttachmentState { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for DiskAttachmentState { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for DiskAttachmentState { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::default::Default for DiskAttachmentState { + fn default() -> Self { + DiskAttachmentState::Detached + } +} +#[doc = "`EmptyObject`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"properties\": {"] +#[doc = " \"prop\": {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"enum\": ["] +#[doc = " {}"] +#[doc = " ]"] +#[doc = " }"] +#[doc = " }"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +pub struct EmptyObject { + #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] + pub prop: ::std::option::Option, +} +impl ::std::default::Default for EmptyObject { + fn default() -> Self { + Self { + prop: Default::default(), + } + } +} +impl EmptyObject { + pub fn builder() -> builder::EmptyObject { + Default::default() + } +} +#[doc = "`EmptyObjectProp`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"enum\": ["] +#[doc = " {}"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Serialize, Clone, Debug)] +#[serde(transparent)] +pub struct EmptyObjectProp(::serde_json::Map<::std::string::String, ::serde_json::Value>); +impl ::std::ops::Deref for EmptyObjectProp { + type Target = ::serde_json::Map<::std::string::String, ::serde_json::Value>; + fn deref(&self) -> &::serde_json::Map<::std::string::String, ::serde_json::Value> { + &self.0 + } +} +impl ::std::convert::From + for ::serde_json::Map<::std::string::String, ::serde_json::Value> +{ + fn from(value: EmptyObjectProp) -> Self { + value.0 + } +} +impl ::std::convert::TryFrom<::serde_json::Map<::std::string::String, ::serde_json::Value>> + for EmptyObjectProp +{ + type Error = self::error::ConversionError; + fn try_from( + value: ::serde_json::Map<::std::string::String, ::serde_json::Value>, + ) -> ::std::result::Result { + if ![[].into_iter().collect()].contains(&value) { + Err("invalid value".into()) + } else { + Ok(Self(value)) + } + } +} +impl<'de> ::serde::Deserialize<'de> for EmptyObjectProp { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + Self::try_from(<::serde_json::Map< + ::std::string::String, + ::serde_json::Value, + >>::deserialize(deserializer)?) + .map_err(|e| ::custom(e.to_string())) + } +} +impl ::schemars::JsonSchema for EmptyObjectProp { + fn schema_name() -> ::std::string::String { + "EmptyObjectProp".to_string() + } + fn json_schema(gen: &mut ::schemars::gen::SchemaGenerator) -> ::schemars::schema::Schema { + let mut schema = < :: serde_json :: Map < :: std :: string :: String , :: serde_json :: Value > as :: schemars :: JsonSchema > :: json_schema (gen) . into_object () ; + schema.enum_values = ::std::option::Option::Some( + [::serde_json::from_str("{}").unwrap()] + .into_iter() + .collect(), + ); + schema.into() + } +} +#[doc = "`EnumAndConstant`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"required\": ["] +#[doc = " \"bark\","] +#[doc = " \"petType\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"bark\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " \"petType\": {"] +#[doc = " \"type\": \"string\","] +#[doc = " \"enum\": ["] +#[doc = " \"dog\""] +#[doc = " ]"] +#[doc = " }"] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"required\": ["] +#[doc = " \"petType\","] +#[doc = " \"purr\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"petType\": {"] +#[doc = " \"type\": \"string\","] +#[doc = " \"const\": \"cat\""] +#[doc = " },"] +#[doc = " \"purr\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"required\": ["] +#[doc = " \"help\","] +#[doc = " \"petType\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"help\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " \"petType\": {"] +#[doc = " \"const\": \"monkey\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"required\": ["] +#[doc = " \"float\","] +#[doc = " \"petType\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"float\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " \"petType\": {"] +#[doc = " \"enum\": ["] +#[doc = " \"fish\""] +#[doc = " ]"] +#[doc = " }"] +#[doc = " }"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(tag = "petType")] +pub enum EnumAndConstant { + #[serde(rename = "dog")] + Dog { bark: ::std::string::String }, + #[serde(rename = "cat")] + Cat { purr: ::std::string::String }, + #[serde(rename = "monkey")] + Monkey { help: ::std::string::String }, + #[serde(rename = "fish")] + Fish { float: ::std::string::String }, +} +#[doc = "`IpNet`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"title\": \"V4\","] +#[doc = " \"allOf\": ["] +#[doc = " {"] +#[doc = " \"$ref\": \"#/components/schemas/Ipv4Net\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"title\": \"V6\","] +#[doc = " \"allOf\": ["] +#[doc = " {"] +#[doc = " \"$ref\": \"#/components/schemas/Ipv6Net\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = " }"] +#[doc = " ],"] +#[doc = " \"$comment\": \"we want to see *nice* variant names in the output\""] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum IpNet { + V4(Ipv4Net), + V6(Ipv6Net), +} +impl ::std::str::FromStr for IpNet { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + if let Ok(v) = value.parse() { + Ok(Self::V4(v)) + } else if let Ok(v) = value.parse() { + Ok(Self::V6(v)) + } else { + Err("string conversion failed for all variants".into()) + } + } +} +impl ::std::convert::TryFrom<&str> for IpNet { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for IpNet { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for IpNet { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::fmt::Display for IpNet { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match self { + Self::V4(x) => x.fmt(f), + Self::V6(x) => x.fmt(f), + } + } +} +impl ::std::convert::From for IpNet { + fn from(value: Ipv4Net) -> Self { + Self::V4(value) + } +} +impl ::std::convert::From for IpNet { + fn from(value: Ipv6Net) -> Self { + Self::V6(value) + } +} +#[doc = "`Ipv4Net`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"string\","] +#[doc = " \"pattern\": \".*\""] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(transparent)] +pub struct Ipv4Net(::std::string::String); +impl ::std::ops::Deref for Ipv4Net { + type Target = ::std::string::String; + fn deref(&self) -> &::std::string::String { + &self.0 + } +} +impl ::std::convert::From for ::std::string::String { + fn from(value: Ipv4Net) -> Self { + value.0 + } +} +impl ::std::str::FromStr for Ipv4Net { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + static PATTERN: ::std::sync::LazyLock<::regress::Regex> = + ::std::sync::LazyLock::new(|| ::regress::Regex::new(".*").unwrap()); + if PATTERN.find(value).is_none() { + return Err("doesn't match pattern \".*\"".into()); + } + Ok(Self(value.to_string())) + } +} +impl ::std::convert::TryFrom<&str> for Ipv4Net { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for Ipv4Net { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for Ipv4Net { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl<'de> ::serde::Deserialize<'de> for Ipv4Net { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + ::std::string::String::deserialize(deserializer)? + .parse() + .map_err(|e: self::error::ConversionError| { + ::custom(e.to_string()) + }) + } +} +#[doc = "`Ipv6Net`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"string\","] +#[doc = " \"pattern\": \".*\""] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(transparent)] +pub struct Ipv6Net(::std::string::String); +impl ::std::ops::Deref for Ipv6Net { + type Target = ::std::string::String; + fn deref(&self) -> &::std::string::String { + &self.0 + } +} +impl ::std::convert::From for ::std::string::String { + fn from(value: Ipv6Net) -> Self { + value.0 + } +} +impl ::std::str::FromStr for Ipv6Net { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + static PATTERN: ::std::sync::LazyLock<::regress::Regex> = + ::std::sync::LazyLock::new(|| ::regress::Regex::new(".*").unwrap()); + if PATTERN.find(value).is_none() { + return Err("doesn't match pattern \".*\"".into()); + } + Ok(Self(value.to_string())) + } +} +impl ::std::convert::TryFrom<&str> for Ipv6Net { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for Ipv6Net { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for Ipv6Net { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl<'de> ::serde::Deserialize<'de> for Ipv6Net { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + ::std::string::String::deserialize(deserializer)? + .parse() + .map_err(|e: self::error::ConversionError| { + ::custom(e.to_string()) + }) + } +} +#[doc = "`JankNames`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"title\": \"Animation Specification\","] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"title\": \"Animation Specification\","] +#[doc = " \"type\": \"object\","] +#[doc = " \"maxProperties\": 1,"] +#[doc = " \"minProperties\": 1,"] +#[doc = " \"additionalProperties\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"maxProperties\": 2,"] +#[doc = " \"minProperties\": 2,"] +#[doc = " \"additionalProperties\": {"] +#[doc = " \"type\": \"integer\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum JankNames { + Variant0(::std::string::String), + Variant1(::std::collections::HashMap<::std::string::String, ::std::string::String>), + Variant2(::std::collections::HashMap<::std::string::String, i64>), +} +impl ::std::convert::From<::std::collections::HashMap<::std::string::String, ::std::string::String>> + for JankNames +{ + fn from( + value: ::std::collections::HashMap<::std::string::String, ::std::string::String>, + ) -> Self { + Self::Variant1(value) + } +} +impl ::std::convert::From<::std::collections::HashMap<::std::string::String, i64>> for JankNames { + fn from(value: ::std::collections::HashMap<::std::string::String, i64>) -> Self { + Self::Variant2(value) + } +} +#[doc = "`Never`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "false"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(deny_unknown_fields)] +pub enum Never {} +#[doc = "`NeverEver`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "false"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(deny_unknown_fields)] +pub enum NeverEver {} +#[doc = "`NeverEverForever`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "false"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(deny_unknown_fields)] +pub enum NeverEverForever {} +#[doc = "`NotBlockSize`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"integer\","] +#[doc = " \"not\": {"] +#[doc = " \"enum\": ["] +#[doc = " 512,"] +#[doc = " 2048,"] +#[doc = " 4096"] +#[doc = " ]"] +#[doc = " }"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Serialize, Clone, Debug)] +#[serde(transparent)] +pub struct NotBlockSize(f64); +impl ::std::ops::Deref for NotBlockSize { + type Target = f64; + fn deref(&self) -> &f64 { + &self.0 + } +} +impl ::std::convert::From for f64 { + fn from(value: NotBlockSize) -> Self { + value.0 + } +} +impl ::std::convert::TryFrom for NotBlockSize { + type Error = self::error::ConversionError; + fn try_from(value: f64) -> ::std::result::Result { + if [512_f64, 2048_f64, 4096_f64].contains(&value) { + Err("invalid value".into()) + } else { + Ok(Self(value)) + } + } +} +impl<'de> ::serde::Deserialize<'de> for NotBlockSize { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + Self::try_from(::deserialize(deserializer)?) + .map_err(|e| ::custom(e.to_string())) + } +} +impl ::schemars::JsonSchema for NotBlockSize { + fn schema_name() -> ::std::string::String { + "NotBlockSize".to_string() + } + fn json_schema(gen: &mut ::schemars::gen::SchemaGenerator) -> ::schemars::schema::Schema { + let mut schema = ::json_schema(gen).into_object(); + let not = ::schemars::schema::SchemaObject { + enum_values: ::std::option::Option::Some( + [ + ::serde_json::from_str("512").unwrap(), + ::serde_json::from_str("2048").unwrap(), + ::serde_json::from_str("4096").unwrap(), + ] + .into_iter() + .collect(), + ), + ..::std::default::Default::default() + }; + schema.subschemas().not = Some(::std::boxed::Box::new(not.into())); + schema.into() + } +} +#[doc = "`NullStringEnumWithUnknownFormat`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": ["] +#[doc = " \"string\","] +#[doc = " \"null\""] +#[doc = " ],"] +#[doc = " \"format\": \"?\","] +#[doc = " \"enum\": ["] +#[doc = " \"a\","] +#[doc = " \"b\","] +#[doc = " \"c\""] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct NullStringEnumWithUnknownFormat( + pub ::std::option::Option, +); +impl ::std::ops::Deref for NullStringEnumWithUnknownFormat { + type Target = ::std::option::Option; + fn deref(&self) -> &::std::option::Option { + &self.0 + } +} +impl ::std::convert::From + for ::std::option::Option +{ + fn from(value: NullStringEnumWithUnknownFormat) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option> + for NullStringEnumWithUnknownFormat +{ + fn from(value: ::std::option::Option) -> Self { + Self(value) + } +} +#[doc = "`NullStringEnumWithUnknownFormatInner`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"string\","] +#[doc = " \"format\": \"?\","] +#[doc = " \"enum\": ["] +#[doc = " \"a\","] +#[doc = " \"b\","] +#[doc = " \"c\""] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +pub enum NullStringEnumWithUnknownFormatInner { + #[serde(rename = "a")] + A, + #[serde(rename = "b")] + B, + #[serde(rename = "c")] + C, +} +impl ::std::fmt::Display for NullStringEnumWithUnknownFormatInner { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match *self { + Self::A => f.write_str("a"), + Self::B => f.write_str("b"), + Self::C => f.write_str("c"), + } + } +} +impl ::std::str::FromStr for NullStringEnumWithUnknownFormatInner { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + match value { + "a" => Ok(Self::A), + "b" => Ok(Self::B), + "c" => Ok(Self::C), + _ => Err("invalid value".into()), + } + } +} +impl ::std::convert::TryFrom<&str> for NullStringEnumWithUnknownFormatInner { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for NullStringEnumWithUnknownFormatInner { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for NullStringEnumWithUnknownFormatInner { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +#[doc = "`OneOfMissingTitle`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"title\": \"A\","] +#[doc = " \"properties\": {"] +#[doc = " \"foo\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"title\": \"B\","] +#[doc = " \"properties\": {"] +#[doc = " \"bar\": {"] +#[doc = " \"type\": \"integer\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"properties\": {"] +#[doc = " \"bar\": {"] +#[doc = " \"type\": \"integer\""] +#[doc = " },"] +#[doc = " \"baz\": {"] +#[doc = " \"type\": \"integer\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum OneOfMissingTitle { + Variant0 { + #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] + foo: ::std::option::Option<::std::string::String>, + }, + Variant1 { + #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] + bar: ::std::option::Option, + }, + Variant2 { + #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] + bar: ::std::option::Option, + #[serde(default, skip_serializing_if = "::std::option::Option::is_none")] + baz: ::std::option::Option, + }, +} +#[doc = "`OneOfRawType`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"integer\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum OneOfRawType { + String(::std::string::String), + Integer(i64), +} +impl ::std::fmt::Display for OneOfRawType { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match self { + Self::String(x) => x.fmt(f), + Self::Integer(x) => x.fmt(f), + } + } +} +impl ::std::convert::From for OneOfRawType { + fn from(value: i64) -> Self { + Self::Integer(value) + } +} +#[doc = "`OneOfTypes`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"required\": ["] +#[doc = " \"bar\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"bar\": {"] +#[doc = " \"type\": \"integer\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"required\": ["] +#[doc = " \"foo\""] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"foo\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " }"] +#[doc = " }"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +pub enum OneOfTypes { + #[serde(rename = "bar")] + Bar(i64), + #[serde(rename = "foo")] + Foo(::std::string::String), +} +impl ::std::convert::From for OneOfTypes { + fn from(value: i64) -> Self { + Self::Bar(value) + } +} +#[doc = "`OptionAnyofConst`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"anyOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"const\": null"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct OptionAnyofConst(pub ::std::option::Option<::std::string::String>); +impl ::std::ops::Deref for OptionAnyofConst { + type Target = ::std::option::Option<::std::string::String>; + fn deref(&self) -> &::std::option::Option<::std::string::String> { + &self.0 + } +} +impl ::std::convert::From for ::std::option::Option<::std::string::String> { + fn from(value: OptionAnyofConst) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option<::std::string::String>> for OptionAnyofConst { + fn from(value: ::std::option::Option<::std::string::String>) -> Self { + Self(value) + } +} +#[doc = "`OptionAnyofEnum`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"anyOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"enum\": ["] +#[doc = " null"] +#[doc = " ]"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct OptionAnyofEnum(pub ::std::option::Option<::std::string::String>); +impl ::std::ops::Deref for OptionAnyofEnum { + type Target = ::std::option::Option<::std::string::String>; + fn deref(&self) -> &::std::option::Option<::std::string::String> { + &self.0 + } +} +impl ::std::convert::From for ::std::option::Option<::std::string::String> { + fn from(value: OptionAnyofEnum) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option<::std::string::String>> for OptionAnyofEnum { + fn from(value: ::std::option::Option<::std::string::String>) -> Self { + Self(value) + } +} +#[doc = "`OptionAnyofNull`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"anyOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"null\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct OptionAnyofNull(pub ::std::option::Option<::std::string::String>); +impl ::std::ops::Deref for OptionAnyofNull { + type Target = ::std::option::Option<::std::string::String>; + fn deref(&self) -> &::std::option::Option<::std::string::String> { + &self.0 + } +} +impl ::std::convert::From for ::std::option::Option<::std::string::String> { + fn from(value: OptionAnyofNull) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option<::std::string::String>> for OptionAnyofNull { + fn from(value: ::std::option::Option<::std::string::String>) -> Self { + Self(value) + } +} +#[doc = "`OptionOneofConst`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"const\": null"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct OptionOneofConst(pub ::std::option::Option<::std::string::String>); +impl ::std::ops::Deref for OptionOneofConst { + type Target = ::std::option::Option<::std::string::String>; + fn deref(&self) -> &::std::option::Option<::std::string::String> { + &self.0 + } +} +impl ::std::convert::From for ::std::option::Option<::std::string::String> { + fn from(value: OptionOneofConst) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option<::std::string::String>> for OptionOneofConst { + fn from(value: ::std::option::Option<::std::string::String>) -> Self { + Self(value) + } +} +#[doc = "`OptionOneofEnum`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"enum\": ["] +#[doc = " null"] +#[doc = " ]"] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct OptionOneofEnum(pub ::std::option::Option<::std::string::String>); +impl ::std::ops::Deref for OptionOneofEnum { + type Target = ::std::option::Option<::std::string::String>; + fn deref(&self) -> &::std::option::Option<::std::string::String> { + &self.0 + } +} +impl ::std::convert::From for ::std::option::Option<::std::string::String> { + fn from(value: OptionOneofEnum) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option<::std::string::String>> for OptionOneofEnum { + fn from(value: ::std::option::Option<::std::string::String>) -> Self { + Self(value) + } +} +#[doc = "`OptionOneofNull`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"null\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(transparent)] +pub struct OptionOneofNull(pub ::std::option::Option<::std::string::String>); +impl ::std::ops::Deref for OptionOneofNull { + type Target = ::std::option::Option<::std::string::String>; + fn deref(&self) -> &::std::option::Option<::std::string::String> { + &self.0 + } +} +impl ::std::convert::From for ::std::option::Option<::std::string::String> { + fn from(value: OptionOneofNull) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::option::Option<::std::string::String>> for OptionOneofNull { + fn from(value: ::std::option::Option<::std::string::String>) -> Self { + Self(value) + } +} +#[doc = "`ReferenceDef`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"string\""] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(transparent)] +pub struct ReferenceDef(pub ::std::string::String); +impl ::std::ops::Deref for ReferenceDef { + type Target = ::std::string::String; + fn deref(&self) -> &::std::string::String { + &self.0 + } +} +impl ::std::convert::From for ::std::string::String { + fn from(value: ReferenceDef) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::string::String> for ReferenceDef { + fn from(value: ::std::string::String) -> Self { + Self(value) + } +} +impl ::std::str::FromStr for ReferenceDef { + type Err = ::std::convert::Infallible; + fn from_str(value: &str) -> ::std::result::Result { + Ok(Self(value.to_string())) + } +} +impl ::std::fmt::Display for ReferenceDef { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + self.0.fmt(f) + } +} +#[doc = "issue 280"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"description\": \"issue 280\","] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"type\": \"array\","] +#[doc = " \"items\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " }"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"type\": \"object\","] +#[doc = " \"additionalProperties\": {"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"$ref\": \"#/definitions/StringVersion\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"$ref\": \"#/definitions/ReferenceDef\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = " },"] +#[doc = " \"$comment\": \"Mapping of mod name to the desired version\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum References { + Array(::std::vec::Vec<::std::string::String>), + Object(::std::collections::HashMap<::std::string::String, ReferencesObjectValue>), +} +impl ::std::convert::From<::std::vec::Vec<::std::string::String>> for References { + fn from(value: ::std::vec::Vec<::std::string::String>) -> Self { + Self::Array(value) + } +} +impl ::std::convert::From<::std::collections::HashMap<::std::string::String, ReferencesObjectValue>> + for References +{ + fn from( + value: ::std::collections::HashMap<::std::string::String, ReferencesObjectValue>, + ) -> Self { + Self::Object(value) + } +} +#[doc = "`ReferencesObjectValue`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"$ref\": \"#/definitions/StringVersion\""] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"$ref\": \"#/definitions/ReferenceDef\""] +#[doc = " }"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum ReferencesObjectValue { + StringVersion(StringVersion), + ReferenceDef(ReferenceDef), +} +impl ::std::fmt::Display for ReferencesObjectValue { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match self { + Self::StringVersion(x) => x.fmt(f), + Self::ReferenceDef(x) => x.fmt(f), + } + } +} +impl ::std::convert::From for ReferencesObjectValue { + fn from(value: StringVersion) -> Self { + Self::StringVersion(value) + } +} +impl ::std::convert::From for ReferencesObjectValue { + fn from(value: ReferenceDef) -> Self { + Self::ReferenceDef(value) + } +} +#[doc = "`ShouldBeExclusive`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"object\","] +#[doc = " \"oneOf\": ["] +#[doc = " {"] +#[doc = " \"required\": ["] +#[doc = " \"id\""] +#[doc = " ]"] +#[doc = " },"] +#[doc = " {"] +#[doc = " \"required\": ["] +#[doc = " \"reference\""] +#[doc = " ]"] +#[doc = " }"] +#[doc = " ],"] +#[doc = " \"properties\": {"] +#[doc = " \"id\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " },"] +#[doc = " \"reference\": {"] +#[doc = " \"type\": \"string\""] +#[doc = " }"] +#[doc = " }"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug, schemars :: JsonSchema)] +#[serde(untagged)] +pub enum ShouldBeExclusive { + Variant0 { id: ::std::string::String }, + Variant1 { reference: ::std::string::String }, +} +#[doc = "`StringVersion`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"string\""] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +#[serde(transparent)] +pub struct StringVersion(pub ::std::string::String); +impl ::std::ops::Deref for StringVersion { + type Target = ::std::string::String; + fn deref(&self) -> &::std::string::String { + &self.0 + } +} +impl ::std::convert::From for ::std::string::String { + fn from(value: StringVersion) -> Self { + value.0 + } +} +impl ::std::convert::From<::std::string::String> for StringVersion { + fn from(value: ::std::string::String) -> Self { + Self(value) + } +} +impl ::std::str::FromStr for StringVersion { + type Err = ::std::convert::Infallible; + fn from_str(value: &str) -> ::std::result::Result { + Ok(Self(value.to_string())) + } +} +impl ::std::fmt::Display for StringVersion { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + self.0.fmt(f) + } +} +#[doc = "`VariantsDifferByPunct`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"enum\": ["] +#[doc = " \"2.5GBASE-T\","] +#[doc = " \"25GBASE-T\","] +#[doc = " \"2,5,GBASE,T\""] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive( + :: serde :: Deserialize, + :: serde :: Serialize, + Clone, + Copy, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + schemars :: JsonSchema, +)] +pub enum VariantsDifferByPunct { + #[serde(rename = "2.5GBASE-T")] + X2x5gbasext, + #[serde(rename = "25GBASE-T")] + X25gbasext, + #[serde(rename = "2,5,GBASE,T")] + X2x5xgbasext, +} +impl ::std::fmt::Display for VariantsDifferByPunct { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + match *self { + Self::X2x5gbasext => f.write_str("2.5GBASE-T"), + Self::X25gbasext => f.write_str("25GBASE-T"), + Self::X2x5xgbasext => f.write_str("2,5,GBASE,T"), + } + } +} +impl ::std::str::FromStr for VariantsDifferByPunct { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> ::std::result::Result { + match value { + "2.5GBASE-T" => Ok(Self::X2x5gbasext), + "25GBASE-T" => Ok(Self::X25gbasext), + "2,5,GBASE,T" => Ok(Self::X2x5xgbasext), + _ => Err("invalid value".into()), + } + } +} +impl ::std::convert::TryFrom<&str> for VariantsDifferByPunct { + type Error = self::error::ConversionError; + fn try_from(value: &str) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<&::std::string::String> for VariantsDifferByPunct { + type Error = self::error::ConversionError; + fn try_from( + value: &::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +impl ::std::convert::TryFrom<::std::string::String> for VariantsDifferByPunct { + type Error = self::error::ConversionError; + fn try_from( + value: ::std::string::String, + ) -> ::std::result::Result { + value.parse() + } +} +#[doc = r" Types for composing complex structures."] +pub mod builder { + #[derive(Clone, Debug)] + pub struct DiskAttachment { + alternate: ::std::result::Result, + state: ::std::result::Result, + } + impl ::std::default::Default for DiskAttachment { + fn default() -> Self { + Self { + alternate: Err("no value supplied for alternate".to_string()), + state: Err("no value supplied for state".to_string()), + } + } + } + impl DiskAttachment { + pub fn alternate(mut self, value: T) -> Self + where + T: ::std::convert::TryInto, + T::Error: ::std::fmt::Display, + { + self.alternate = value + .try_into() + .map_err(|e| format!("error converting supplied value for alternate: {e}")); + self + } + pub fn state(mut self, value: T) -> Self + where + T: ::std::convert::TryInto, + T::Error: ::std::fmt::Display, + { + self.state = value + .try_into() + .map_err(|e| format!("error converting supplied value for state: {e}")); + self + } + } + impl ::std::convert::TryFrom for super::DiskAttachment { + type Error = super::error::ConversionError; + fn try_from( + value: DiskAttachment, + ) -> ::std::result::Result { + Ok(Self { + alternate: value.alternate?, + state: value.state?, + }) + } + } + impl ::std::convert::From for DiskAttachment { + fn from(value: super::DiskAttachment) -> Self { + Self { + alternate: Ok(value.alternate), + state: Ok(value.state), + } + } + } + #[derive(Clone, Debug)] + pub struct EmptyObject { + prop: ::std::result::Result< + ::std::option::Option, + ::std::string::String, + >, + } + impl ::std::default::Default for EmptyObject { + fn default() -> Self { + Self { + prop: Ok(Default::default()), + } + } + } + impl EmptyObject { + pub fn prop(mut self, value: T) -> Self + where + T: ::std::convert::TryInto<::std::option::Option>, + T::Error: ::std::fmt::Display, + { + self.prop = value + .try_into() + .map_err(|e| format!("error converting supplied value for prop: {e}")); + self + } + } + impl ::std::convert::TryFrom for super::EmptyObject { + type Error = super::error::ConversionError; + fn try_from( + value: EmptyObject, + ) -> ::std::result::Result { + Ok(Self { prop: value.prop? }) + } + } + impl ::std::convert::From for EmptyObject { + fn from(value: super::EmptyObject) -> Self { + Self { + prop: Ok(value.prop), + } + } + } +} +fn main() {} diff --git a/typify/tests/schemas/various-enums.json b/typify/tests/schemas/various-enums.json index 6d058e8b..4f460f8a 100644 --- a/typify/tests/schemas/various-enums.json +++ b/typify/tests/schemas/various-enums.json @@ -64,7 +64,7 @@ "type": "integer" } } - } + } ] }, "IpNet": { @@ -402,6 +402,24 @@ "type": "null" } ] + }, + "BlockSize": { + "type": "integer", + "enum": [ + 512, + 2048, + 4096 + ] + }, + "NotBlockSize": { + "type": "integer", + "not": { + "enum": [ + 512, + 2048, + 4096 + ] + } } } } diff --git a/typify/tests/schemas/various-enums.rs b/typify/tests/schemas/various-enums.rs index 2272fecd..b252bcd3 100644 --- a/typify/tests/schemas/various-enums.rs +++ b/typify/tests/schemas/various-enums.rs @@ -154,6 +154,54 @@ pub enum AnyOfNoStrings {} )] #[serde(deny_unknown_fields)] pub enum AnyOfNothing {} +#[doc = "`BlockSize`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"integer\","] +#[doc = " \"enum\": ["] +#[doc = " 512,"] +#[doc = " 2048,"] +#[doc = " 4096"] +#[doc = " ]"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Serialize, Clone, Debug)] +#[serde(transparent)] +pub struct BlockSize(i64); +impl ::std::ops::Deref for BlockSize { + type Target = i64; + fn deref(&self) -> &i64 { + &self.0 + } +} +impl ::std::convert::From for i64 { + fn from(value: BlockSize) -> Self { + value.0 + } +} +impl ::std::convert::TryFrom for BlockSize { + type Error = self::error::ConversionError; + fn try_from(value: i64) -> ::std::result::Result { + if ![512_i64, 2048_i64, 4096_i64].contains(&value) { + Err("invalid value".into()) + } else { + Ok(Self(value)) + } + } +} +impl<'de> ::serde::Deserialize<'de> for BlockSize { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + Self::try_from(::deserialize(deserializer)?) + .map_err(|e| ::custom(e.to_string())) + } +} #[doc = "`CommentedVariants`"] #[doc = r""] #[doc = r"
JSON schema"] @@ -885,6 +933,56 @@ pub enum NeverEver {} )] #[serde(deny_unknown_fields)] pub enum NeverEverForever {} +#[doc = "`NotBlockSize`"] +#[doc = r""] +#[doc = r"
JSON schema"] +#[doc = r""] +#[doc = r" ```json"] +#[doc = "{"] +#[doc = " \"type\": \"integer\","] +#[doc = " \"not\": {"] +#[doc = " \"enum\": ["] +#[doc = " 512,"] +#[doc = " 2048,"] +#[doc = " 4096"] +#[doc = " ]"] +#[doc = " }"] +#[doc = "}"] +#[doc = r" ```"] +#[doc = r"
"] +#[derive(:: serde :: Serialize, Clone, Debug)] +#[serde(transparent)] +pub struct NotBlockSize(f64); +impl ::std::ops::Deref for NotBlockSize { + type Target = f64; + fn deref(&self) -> &f64 { + &self.0 + } +} +impl ::std::convert::From for f64 { + fn from(value: NotBlockSize) -> Self { + value.0 + } +} +impl ::std::convert::TryFrom for NotBlockSize { + type Error = self::error::ConversionError; + fn try_from(value: f64) -> ::std::result::Result { + if [512_f64, 2048_f64, 4096_f64].contains(&value) { + Err("invalid value".into()) + } else { + Ok(Self(value)) + } + } +} +impl<'de> ::serde::Deserialize<'de> for NotBlockSize { + fn deserialize(deserializer: D) -> ::std::result::Result + where + D: ::serde::Deserializer<'de>, + { + Self::try_from(::deserialize(deserializer)?) + .map_err(|e| ::custom(e.to_string())) + } +} #[doc = "`NullStringEnumWithUnknownFormat`"] #[doc = r""] #[doc = r"
JSON schema"]