//! Display trait implementation generation for struct errors

use proc_macro2::TokenStream;
use quote::quote;

use crate::ir::StructDefinition;

/// Generate the Display trait implementation
pub fn generate_display_impl(ir: &StructDefinition) -> TokenStream {
    let name = &ir.name;
    let (impl_generics, ty_generics, where_clause) = ir.generics.split_for_impl();
    let message = &ir.error_message;

    // Create local bindings for all fields so format strings can reference them
    let field_bindings: Vec<_> = ir
        .fields
        .iter()
        .map(|field| {
            let rust_name = &field.rust_name;
            quote! { let #rust_name = &self.#rust_name; }
        })
        .collect();

    quote! {
        #[automatically_derived]
        impl #impl_generics ::std::fmt::Display for #name #ty_generics #where_clause {
            fn fmt(&self, __apollo_formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                #(#field_bindings)*
                write!(__apollo_formatter, #message)
            }
        }
    }
}
