fn generate_schema_kind_type()

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(())
}