use proc_macro2::TokenStream;
use quote::quote;
use crate::ir::{EnumDefinition, VariantDefinition};
pub fn generate_from_impls(ir: &EnumDefinition) -> TokenStream {
let name = &ir.name;
let (impl_generics, ty_generics, where_clause) = ir.generics.split_for_impl();
let from_impls: Vec<TokenStream> = ir
.variants
.iter()
.filter_map(|variant| {
match variant {
VariantDefinition::Regular(regular) => {
let from_field = regular.fields.iter().find(|f| f.is_from)?;
let variant_name = ®ular.name;
let field_type = &from_field.ty;
let field_name = &from_field.rust_name;
Some(quote! {
#[automatically_derived]
impl #impl_generics ::std::convert::From<#field_type> for #name #ty_generics #where_clause {
fn from(source: #field_type) -> Self {
Self::#variant_name { #field_name: source }
}
}
})
}
VariantDefinition::Transparent(transparent) => {
if !transparent.field.is_from {
return None;
}
let variant_name = &transparent.name;
let inner_type = &transparent.field.ty;
Some(quote! {
#[automatically_derived]
impl #impl_generics ::std::convert::From<#inner_type> for #name #ty_generics #where_clause {
fn from(source: #inner_type) -> Self {
Self::#variant_name(source)
}
}
})
}
}
})
.collect();
quote! {
#(#from_impls)*
}
}