use quote::quote;
use syn::DeriveInput;
pub(crate) fn expand_ideal_gas(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let variants = match input.data {
syn::Data::Enum(syn::DataEnum { ref variants, .. }) => variants,
_ => panic!("this derive macro only works on enums"),
};
let ideal_gas = impl_ideal_gas(variants);
Ok(quote! {
#ideal_gas
})
}
fn impl_ideal_gas(
variants: &syn::punctuated::Punctuated<syn::Variant, syn::token::Comma>,
) -> proc_macro2::TokenStream {
let ln_lambda3 = variants.iter().map(|v| {
let name = &v.ident;
if name == "NoModel" {
quote! {
Self::#name => panic!("No ideal gas model initialized!")
}
} else {
quote! {
Self::#name(ideal_gas) => ideal_gas.ln_lambda3(temperature)
}
}
});
let string = variants.iter().map(|v| {
let name = &v.ident;
if name == "NoModel" {
quote! {
Self::#name => panic!("No ideal gas model initialized!")
}
} else {
quote! {
Self::#name(ideal_gas) => ideal_gas.ideal_gas_model()
}
}
});
quote! {
impl IdealGas for IdealGasModel {
fn ln_lambda3<D: DualNum<f64, Inner=f64> + Copy>(&self, temperature: D) -> D {
match self {
#(#ln_lambda3,)*
}
}
fn ideal_gas_model(&self) -> &'static str {
match self {
#(#string,)*
}
}
}
}
}