use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::generator::data::{ComplexType, ComplexTypeAttribute, ComplexTypeStruct};
use super::{Context, Renderer, TypeData};
#[derive(Debug)]
pub struct DefaultsRenderer;
impl Renderer for DefaultsRenderer {
fn render_type(&mut self, ctx: &mut Context<'_, '_>, ty: &TypeData<'_>) {
if let TypeData::Complex(x) = ty {
x.render_defaults(ctx);
}
}
}
impl ComplexType<'_> {
pub(crate) fn render_defaults(&self, ctx: &mut Context<'_, '_>) {
match self {
ComplexType::Enum {
type_: _,
content_type,
} => {
if let Some(content_type) = content_type {
content_type.render_defaults(ctx);
}
}
ComplexType::Struct {
type_,
content_type,
} => {
type_.render_defaults(ctx);
if let Some(content_type) = content_type {
content_type.render_defaults(ctx);
}
}
}
}
}
impl ComplexTypeStruct<'_> {
pub(crate) fn render_defaults(&self, ctx: &mut Context<'_, '_>) {
let type_ident = &self.type_ident;
let mut has_attributes = false;
let attribute_defaults = self
.attributes
.iter()
.filter_map(ComplexTypeAttribute::render_default_fn)
.inspect(|_| has_attributes = true);
let impl_ = quote! {
impl #type_ident {
#( #attribute_defaults )*
}
};
if has_attributes {
ctx.module().append(impl_);
}
}
}
impl ComplexTypeAttribute<'_> {
fn render_default_fn(&self) -> Option<TokenStream> {
let default = self.default_value.as_ref()?;
let target_type = self.target_type.ident();
let default_fn_ident = format_ident!("default_{}", self.ident);
Some(quote! {
#[must_use]
pub fn #default_fn_ident() -> #target_type {
#default
}
})
}
}