in compiler-rs/openapi_to_clients_schema/src/types.rs [185:286]
fn generate_schema_kind_type(
open_api: &OpenAPI,
id: &str,
t: &openapiv3::Type,
base: BaseType,
types: &mut Types,
) -> anyhow::Result<()> {
fn alias(base: BaseType, name: TypeName) -> TypeDefinition {
TypeDefinition::TypeAlias(TypeAlias {
base,
generics: Vec::default(),
typ: name.into(),
variants: None,
})
}
use openapiv3::Type::*;
match t {
//---------------------------------------------------------------------
String(string) if !string.enumeration.is_empty() => {
// Enumeration
let members = string
.enumeration
.iter()
.filter_map(|name| name.as_ref()) // filter empty options. Why are they here?
.map(|name| name.as_str().into())
.collect();
let enum_def = TypeDefinition::Enum(clients_schema::Enum {
base,
members,
is_open: false,
});
types.add(id, enum_def);
}
//---------------------------------------------------------------------
String(_) => types.add(id, alias(base, builtins::STRING.clone())),
//---------------------------------------------------------------------
Boolean(_) => types.add(id, alias(base, builtins::BOOLEAN.clone())),
//---------------------------------------------------------------------
Integer(_) =>
// OpenAPI Integer and Number accept an enumeration, but since it's just a list of valid
// values with no identifier, we can't produce an enum out of that list.
// TODO: choose int/long depending on min/max values
{
types.add(id, alias(base, builtins::LONG.clone()))
}
//---------------------------------------------------------------------
Number(_) => {
// TODO: choose float/double depending on min/max values
types.add(id, alias(base, builtins::DOUBLE.clone()));
}
//---------------------------------------------------------------------
Array(array) => {
// NOTE: array.unique_items indicates a Set. We don't have that in schema.json, and it actually
// doesn't exist in the JSON data model
let items = array
.items
.as_ref()
.ok_or(anyhow!("Array type in '{}' has no items", id))?;
let value = generate_value_of(open_api, items.into(), || format!("{}_arrayitem", id), types)?;
let alias_def = TypeDefinition::TypeAlias(TypeAlias {
base,
typ: ValueOf::ArrayOf(ArrayOf { value: Box::new(value) }),
generics: Vec::default(),
variants: None,
});
types.add(id, alias_def);
}
//---------------------------------------------------------------------
Object(obj) => {
if let (0, Some(ref value)) = (obj.properties.len(), &obj.additional_properties) {
// No fixed properties: it's a dictionary
generate_dictionary_def(open_api, id, base, value, types)?;
} else {
// Regular type
generate_interface_def(
open_api,
id,
base,
&obj.required,
&obj.properties,
&obj.additional_properties,
types,
)?;
}
}
}
Ok(())
}