chore(codegen): updated spec and improved builder ergonomics
This commit is contained in:
parent
84d7c7586b
commit
e5e5d327a2
8 changed files with 5959 additions and 114 deletions
|
|
@ -15,26 +15,51 @@ pub enum EnumRepr {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum EnumVariantTupleValue {
|
||||
Ref(String),
|
||||
Ref { ty_name: String },
|
||||
ArrayOfRefs { ty_name: String },
|
||||
}
|
||||
|
||||
impl EnumVariantTupleValue {
|
||||
pub fn from_schema(schema: &OpenApiType) -> Option<Self> {
|
||||
if let OpenApiType {
|
||||
ref_path: Some(path),
|
||||
..
|
||||
} = schema
|
||||
{
|
||||
Some(Self::Ref((*path).to_owned()))
|
||||
} else {
|
||||
None
|
||||
match schema {
|
||||
OpenApiType {
|
||||
ref_path: Some(path),
|
||||
..
|
||||
} => Some(Self::Ref {
|
||||
ty_name: path.strip_prefix("#/components/schemas/")?.to_owned(),
|
||||
}),
|
||||
OpenApiType {
|
||||
r#type: Some("array"),
|
||||
items: Some(items),
|
||||
..
|
||||
} => {
|
||||
let OpenApiType {
|
||||
ref_path: Some(path),
|
||||
..
|
||||
} = items.as_ref()
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
Some(Self::ArrayOfRefs {
|
||||
ty_name: path.strip_prefix("#/components/schemas/")?.to_owned(),
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
let Self::Ref(path) = self;
|
||||
pub fn type_name(&self) -> &str {
|
||||
match self {
|
||||
Self::Ref { ty_name } => ty_name,
|
||||
Self::ArrayOfRefs { ty_name } => ty_name,
|
||||
}
|
||||
}
|
||||
|
||||
path.strip_prefix("#/components/schemas/")
|
||||
pub fn name(&self) -> String {
|
||||
match self {
|
||||
Self::Ref { ty_name } => ty_name.clone(),
|
||||
Self::ArrayOfRefs { ty_name } => format!("{ty_name}s"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +128,7 @@ impl EnumVariant {
|
|||
let mut val_tys = Vec::with_capacity(values.len());
|
||||
|
||||
for value in values {
|
||||
let ty_name = value.name()?;
|
||||
let ty_name = value.type_name();
|
||||
let ty_name = format_ident!("{ty_name}");
|
||||
|
||||
val_tys.push(quote! {
|
||||
|
|
@ -216,7 +241,7 @@ impl Enum {
|
|||
|
||||
for schema in schemas {
|
||||
let value = EnumVariantTupleValue::from_schema(schema)?;
|
||||
let name = value.name()?.to_owned();
|
||||
let name = value.name();
|
||||
|
||||
result.variants.push(EnumVariant {
|
||||
name,
|
||||
|
|
@ -253,11 +278,15 @@ impl Enum {
|
|||
|
||||
let mut derives = vec![];
|
||||
|
||||
if self.copy {
|
||||
derives.extend_from_slice(&["Copy", "Hash"]);
|
||||
if self.repr.is_some() {
|
||||
derives.push(quote! { serde_repr::Deserialize_repr });
|
||||
} else {
|
||||
derives.push(quote! { serde::Deserialize });
|
||||
}
|
||||
|
||||
let derives = derives.into_iter().map(|d| format_ident!("{d}"));
|
||||
if self.copy {
|
||||
derives.push(quote! { Copy, Hash });
|
||||
}
|
||||
|
||||
let serde_attr = self.untagged.then(|| {
|
||||
quote! {
|
||||
|
|
@ -279,7 +308,7 @@ impl Enum {
|
|||
|
||||
Some(quote! {
|
||||
#desc
|
||||
#[derive(Debug, Clone, PartialEq, serde::Deserialize, #(#derives),*)]
|
||||
#[derive(Debug, Clone, PartialEq, #(#derives),*)]
|
||||
#serde_attr
|
||||
pub enum #name {
|
||||
#(#variants),*
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ impl Object {
|
|||
|
||||
for (prop_name, prop) in props {
|
||||
// HACK: This will cause a duplicate key otherwise
|
||||
if *prop_name == "itemDetails" {
|
||||
if ["itemDetails", "sci-fi", "non-attackers", "co-leader_id"].contains(prop_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,6 +217,12 @@ impl Parameter {
|
|||
Self(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for #name {
|
||||
fn from(inner: i32) -> Self {
|
||||
Self(inner)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -317,6 +323,14 @@ The default value [Self::{}](self::{}#variant.{})"#,
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for #name where T: IntoIterator<Item = #inner_ty> {
|
||||
fn from(value: T) -> #name {
|
||||
let items = value.into_iter().collect();
|
||||
|
||||
Self(items)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Some(code)
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ impl Path {
|
|||
PathParameter::Component(param) => (false, param),
|
||||
};
|
||||
|
||||
let ty = match ¶m.r#type {
|
||||
let (ty, builder_param) = match ¶m.r#type {
|
||||
ParameterType::I32 { .. } | ParameterType::Enum { .. } => {
|
||||
let ty_name = format_ident!("{}", param.name);
|
||||
|
||||
|
|
@ -162,31 +162,43 @@ impl Path {
|
|||
ns.push_element(param.codegen()?);
|
||||
let path = ns.get_ident();
|
||||
|
||||
quote! {
|
||||
crate::request::models::#path::#ty_name
|
||||
}
|
||||
(
|
||||
quote! {
|
||||
crate::request::models::#path::#ty_name
|
||||
},
|
||||
Some(quote! { #[builder(into)] }),
|
||||
)
|
||||
} else {
|
||||
quote! {
|
||||
crate::parameters::#ty_name
|
||||
}
|
||||
(
|
||||
quote! {
|
||||
crate::parameters::#ty_name
|
||||
},
|
||||
Some(quote! { #[builder(into)]}),
|
||||
)
|
||||
}
|
||||
}
|
||||
ParameterType::String => quote! { String },
|
||||
ParameterType::Boolean => quote! { bool },
|
||||
ParameterType::String => (quote! { String }, None),
|
||||
ParameterType::Boolean => (quote! { bool }, None),
|
||||
ParameterType::Schema { type_name } => {
|
||||
let ty_name = format_ident!("{}", type_name);
|
||||
|
||||
quote! {
|
||||
crate::models::#ty_name
|
||||
}
|
||||
(
|
||||
quote! {
|
||||
crate::models::#ty_name
|
||||
},
|
||||
None,
|
||||
)
|
||||
}
|
||||
ParameterType::Array { .. } => {
|
||||
ns.push_element(param.codegen()?);
|
||||
let ty_name = param.r#type.codegen_type_name(¶m.name);
|
||||
let path = ns.get_ident();
|
||||
quote! {
|
||||
crate::request::models::#path::#ty_name
|
||||
}
|
||||
(
|
||||
quote! {
|
||||
crate::request::models::#path::#ty_name
|
||||
},
|
||||
Some(quote! { #[builder(into)] }),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -199,6 +211,7 @@ impl Path {
|
|||
let path_name = format_ident!("{}", param.value);
|
||||
start_fields.push(quote! {
|
||||
#[builder(start_fn)]
|
||||
#builder_param
|
||||
pub #name: #ty
|
||||
});
|
||||
fmt_val.push(quote! {
|
||||
|
|
@ -218,6 +231,7 @@ impl Path {
|
|||
};
|
||||
|
||||
fields.push(quote! {
|
||||
#builder_param
|
||||
pub #name: #ty
|
||||
});
|
||||
}
|
||||
|
|
@ -260,7 +274,7 @@ impl Path {
|
|||
#ns
|
||||
|
||||
#[derive(Debug, Clone, bon::Builder)]
|
||||
#[builder(state_mod(vis = "pub(crate)"))]
|
||||
#[builder(state_mod(vis = "pub(crate)"), on(String, into))]
|
||||
pub struct #name {
|
||||
#(#start_fields),*
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue