fn derive_fmt_any()

in amzn-smt-ir-derive/src/lib.rs [274:349]


fn derive_fmt_any(s: &synstructure::Structure, trait_path: syn::Path) -> TokenStream {
    let smt_ir = smt_ir_crate_path();

    #[allow(non_snake_case)]
    let Format = quote!(#smt_ir::term::args::Format);

    let fmt_body = s.each_variant(|variant| {
        let symbol = variant_symbol(variant);
        let bindings = variant.bindings();
        if bindings.is_empty() {
            quote!(std::write!(f, #symbol))
        } else {
            let mut fmt_indices = None;
            let fmt_fields: Vec<_> = bindings
                .iter()
                .filter_map(|field| {
                    if index_array(&field.ast().ty).is_some() {
                        fmt_indices = Some(quote! {
                            for index in #field {
                                std::write!(f, " {}", index)?;
                            }
                        });
                        None
                    } else {
                        Some(quote! {
                            std::write!(f, " ")?;
                            #Format::fmt(#field, f, #trait_path::fmt)
                        })
                    }
                })
                .collect();
            let fmt_func = if let Some(fmt_indices) = fmt_indices {
                quote! {
                    std::write!(f, "(_ {}", #symbol)?;
                    #fmt_indices
                    std::write!(f, ")")
                }
            } else {
                quote!(std::write!(f, #symbol))
            };
            quote! {
                std::write!(f, "(")?;
                #fmt_func?;
                #(#fmt_fields?;)*
                std::write!(f, ")")
            }
        }
    });

    let mut where_clause = None;
    s.add_trait_bounds(
        &parse_quote!(std::fmt::Debug),
        &mut where_clause,
        synstructure::AddBounds::Generics,
    );
    s.add_trait_bounds(
        &parse_quote!(std::fmt::Display),
        &mut where_clause,
        synstructure::AddBounds::Generics,
    );
    s.add_trait_bounds(
        &parse_quote!(#Format),
        &mut where_clause,
        synstructure::AddBounds::Generics,
    );
    s.gen_impl(quote! {
        extern crate std;
        gen impl #trait_path for @Self #where_clause {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                match self {
                    #fmt_body
                }
            }
        }
    })
}