use proc_macro::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::Type;
use synext::{try_derive_input, try_parse_named_fields};
const GETTER_PREFIX: &str = "get_";
pub(crate) fn derive_getter(input: TokenStream) -> TokenStream {
let derive_input = try_derive_input(input);
let struct_name = &derive_input.ident;
let (impl_generics, ty_generics, where_clause) = &derive_input.generics.split_for_impl();
let mut getters = Vec::new();
let fields = try_parse_named_fields(&derive_input);
fields.iter().for_each(|field| {
let field_name = field.ident.clone().unwrap();
let field_type = &field.ty;
let return_type = match field_type {
Type::Reference(ref_type) => ref_type.to_token_stream(),
_ => quote! { &#field_type },
};
let getter_name = format_ident!("{}{}", GETTER_PREFIX, field_name);
let getter = quote! {
pub fn #getter_name(&self) -> #return_type {
&self.#field_name
}
};
getters.push(getter);
let fluent_getter_name = format_ident!("{}", field_name);
let fluent_getter = quote! {
pub fn #fluent_getter_name(&self) -> #return_type {
&self.#field_name
}
};
getters.push(fluent_getter);
});
let expanded = quote! {
impl #impl_generics #struct_name #ty_generics #where_clause {
#(
#getters
)*
}
};
TokenStream::from(expanded)
}