diff --git a/typify-impl/src/enums.rs b/typify-impl/src/enums.rs index ff4c682c..cc35a0e1 100644 --- a/typify-impl/src/enums.rs +++ b/typify-impl/src/enums.rs @@ -89,10 +89,10 @@ impl TypeSpace { // variant that we'd never use... I guess. Schema::Bool(false) => todo!(), - // Strings must be simple enumerations. + // Strings must be simple enumerations or constants. Schema::Object(SchemaObject { metadata, - instance_type: Some(SingleOrVec::Single(single)), + instance_type, format: None, enum_values: Some(values), const_value: None, @@ -103,7 +103,13 @@ impl TypeSpace { object: _, reference: None, extensions: _, - }) if single.as_ref() == &InstanceType::String => { + }) => { + match instance_type { + Some(SingleOrVec::Single(single)) + if single.as_ref() == &InstanceType::String => {} + None => {} + _ => return None, + }; // Confirm that all values are, in fact, simple strings. // Simple strings become simple variants. If any is not // a string, we'll end up returning None @@ -117,6 +123,33 @@ impl TypeSpace { }) .collect() } + Schema::Object(SchemaObject { + metadata, + instance_type, + format: None, + enum_values: None, + const_value: Some(value), + subschemas: None, + number: _, + string: _, + array: _, + object: _, + reference: None, + extensions: _, + }) => { + match instance_type { + Some(SingleOrVec::Single(single)) + if single.as_ref() == &InstanceType::String => {} + None => {} + _ => return None, + }; + std::iter::once(value.as_str().map(|variant_name| ProtoVariant::Simple { + name: variant_name, + description: metadata_description(metadata), + })) + .collect() + } + other => match get_object(other) { // Objects must have a single property, and that // property must be required. The type of that lone diff --git a/typify/tests/schemas/various-enums.json b/typify/tests/schemas/various-enums.json index 874b1563..772318b0 100644 --- a/typify/tests/schemas/various-enums.json +++ b/typify/tests/schemas/various-enums.json @@ -258,6 +258,26 @@ } } ] + }, + "commented-variants": { + "oneOf": [ + { + "enum": [ + "A" + ], + "description": "An A" + }, + { + "enum": [ + "B" + ], + "description": "A B" + }, + { + "const": "C", + "description": "a pirate's favorite letter" + } + ] } } } \ No newline at end of file diff --git a/typify/tests/schemas/various-enums.rs b/typify/tests/schemas/various-enums.rs index 4934278b..8a22181e 100644 --- a/typify/tests/schemas/various-enums.rs +++ b/typify/tests/schemas/various-enums.rs @@ -96,6 +96,85 @@ impl Default for AlternativeEnum { AlternativeEnum::Choice2 } } +#[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(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] +pub enum CommentedVariants { + #[doc = "An A"] + A, + #[doc = "A B"] + B, + #[doc = "a pirate's favorite letter"] + C, +} +impl From<&CommentedVariants> for CommentedVariants { + fn from(value: &CommentedVariants) -> Self { + value.clone() + } +} +impl ToString for CommentedVariants { + fn to_string(&self) -> String { + match *self { + Self::A => "A".to_string(), + Self::B => "B".to_string(), + Self::C => "C".to_string(), + } + } +} +impl std::str::FromStr for CommentedVariants { + type Err = self::error::ConversionError; + fn from_str(value: &str) -> 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) -> Result { + value.parse() + } +} +impl std::convert::TryFrom<&String> for CommentedVariants { + type Error = self::error::ConversionError; + fn try_from(value: &String) -> Result { + value.parse() + } +} +impl std::convert::TryFrom for CommentedVariants { + type Error = self::error::ConversionError; + fn try_from(value: String) -> Result { + value.parse() + } +} #[doc = "DiskAttachment"] #[doc = r""] #[doc = r"
JSON schema"]