use crate::bindgen;
use check_keyword::CheckKeyword;
use openapiv3::{ReferenceOr, Schema, SchemaKind, Type};
pub fn generate(
name: &str,
schema: &Schema,
workaround_mode: bool,
patch_prefix: &str,
) -> Option<String> {
let typ = match &schema.schema_kind {
SchemaKind::Type(x) => x,
_ => return None,
};
let mut result =
"#[derive(Serialize, Deserialize, Debug, Default, Clone)]\npub struct ".to_owned();
result += name;
match &typ {
Type::Object(obj) => {
result += " {\n";
for (prop_name, prop) in &obj.properties {
let p = prop.clone().unbox();
let type_name = bindgen::type_to_string(&p);
if let ReferenceOr::Item(item) = &p {
if let Some(desc) = &item.schema_data.description {
result += bindgen::make_comment(Some(desc.clone()), 1).as_str();
}
}
result += "\t";
if !patch_prefix.is_empty() && name.starts_with(patch_prefix) {
result += "#[serde(skip_serializing_if = \"Option::is_none\")]\n\t";
}
result += "pub ";
result += &prop_name.clone().into_safe();
result += ": ";
let typ = if !patch_prefix.is_empty() && name.starts_with(patch_prefix) {
format!("Option<{}>", type_name)
} else if workaround_mode
&& !name.ends_with("Request")
&& !type_name.contains("Option")
&& prop_name != "id"
{
format!("Option<{}>", type_name)
} else {
type_name
};
result += &typ;
result += ",\n";
}
result += "}\n";
}
Type::Array(obj) => {
let p = obj.items.clone().unwrap().clone().unbox();
let type_name = bindgen::type_to_string(&p);
if let ReferenceOr::Item(item) = &p {
if let Some(desc) = &item.schema_data.description {
result += bindgen::make_comment(Some(desc.clone()), 1).as_str();
}
}
result += "(pub ";
result += &type_name;
result += ");\n";
}
_ => {
return None;
}
}
Some(result)
}
#[cfg(test)]
mod tests {
use super::*;
use openapiv3::{Schema, SchemaKind, StringType, Type};
#[test]
fn test_generate_with_non_object_schema() {
let schema = Schema {
schema_data: Default::default(),
schema_kind: SchemaKind::Type(Type::String(StringType {
..Default::default()
})), };
let result = generate("InvalidStruct", &schema, false, "Patched");
assert_eq!(result, None);
}
}