fields-converter-derive 0.1.4

Fields-wise type conversions derive macros
Documentation
use quote::ToTokens;
use struct_data::{Field, StructData};
use syn;

pub fn eq_fields(struct_data: &StructData, ty_dest: &syn::Path) -> impl ToTokens {
    let (impl_generics, ty_generics, where_clause) = struct_data.generics.split_for_impl();
    let cmps = struct_data
        .field_idents
        .iter()
        .map(|Field { id, .. }| quote!( PartialEq::eq(&self.#id, &other.#id) ));
    let cmps2 = cmps.clone();
    let ty_orig = &struct_data.name;
    quote!(
        impl #impl_generics PartialEq<#ty_dest #ty_generics> for #ty_orig #ty_generics #where_clause {
            fn eq(&self, other: &#ty_dest #ty_generics) -> bool {
                true #(&& #cmps )*
            }
        }

        impl #impl_generics PartialEq<#ty_orig #ty_generics> for #ty_dest #ty_generics #where_clause {
            fn eq(&self, other: &#ty_orig #ty_generics) -> bool {
                true #(&& #cmps2 )*
            }
        }
    )
}

pub fn ord_fields(struct_data: &StructData, ty_dest: &syn::Path) -> impl ToTokens {
    let (impl_generics, ty_generics, where_clause) = struct_data.generics.split_for_impl();
    let cmps = struct_data
        .field_idents
        .iter()
        .map(|Field { id, .. }| quote!( PartialOrd::partial_cmp(&self.#id, &other.#id) ));
    let cmps2 = cmps.clone();
    let ty_orig = &struct_data.name;
    quote!(
        impl #impl_generics PartialOrd<#ty_dest #ty_generics> for #ty_orig #ty_generics #where_clause {
            fn partial_cmp(&self, other: &#ty_dest #ty_generics) -> Option<::std::cmp::Ordering> {
                Some(::std::cmp::Ordering::Equal)
                    #(.and_then(|prev| #cmps.map(|next| prev.then(next))))*
            }
        }

        impl #impl_generics PartialOrd<#ty_orig #ty_generics> for #ty_dest #ty_generics #where_clause {
            fn partial_cmp(&self, other: &#ty_orig #ty_generics) -> Option<::std::cmp::Ordering> {
                Some(::std::cmp::Ordering::Equal)
                    #(.and_then(|prev| #cmps2.map(|next| prev.then(next))))*
            }
        }
    )
}