add #[hdl(cmp_eq)] to implement HdlPartialEq automatically

This commit is contained in:
Jacob Lifshay 2025-02-16 20:48:16 -08:00
parent 43797db36e
commit 3458c21f44
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
9 changed files with 351 additions and 20 deletions

View file

@ -83,6 +83,7 @@ impl ParsedBundle {
custom_bounds,
no_static: _,
no_runtime_generics: _,
cmp_eq: _,
} = options.body;
let mut fields = match fields {
syn::Fields::Named(fields) => fields,
@ -437,6 +438,7 @@ impl ToTokens for ParsedBundle {
custom_bounds: _,
no_static,
no_runtime_generics,
cmp_eq,
} = &options.body;
let target = get_target(target, ident);
let mut item_attrs = attrs.clone();
@ -765,6 +767,69 @@ impl ToTokens for ParsedBundle {
}
}
.to_tokens(tokens);
if let Some((cmp_eq,)) = cmp_eq {
let mut where_clause =
Generics::from(generics)
.where_clause
.unwrap_or_else(|| syn::WhereClause {
where_token: Token![where](span),
predicates: Punctuated::new(),
});
let mut fields_cmp_eq = vec![];
let mut fields_cmp_ne = vec![];
for field in fields.named() {
let field_ident = field.ident();
let field_ty = field.ty();
where_clause
.predicates
.push(parse_quote_spanned! {cmp_eq.span=>
#field_ty: ::fayalite::expr::ops::ExprPartialEq<#field_ty>
});
fields_cmp_eq.push(quote_spanned! {span=>
::fayalite::expr::ops::ExprPartialEq::cmp_eq(__lhs.#field_ident, __rhs.#field_ident)
});
fields_cmp_ne.push(quote_spanned! {span=>
::fayalite::expr::ops::ExprPartialEq::cmp_ne(__lhs.#field_ident, __rhs.#field_ident)
});
}
let cmp_eq_body;
let cmp_ne_body;
if fields_len == 0 {
cmp_eq_body = quote_spanned! {span=>
::fayalite::expr::ToExpr::to_expr(&true)
};
cmp_ne_body = quote_spanned! {span=>
::fayalite::expr::ToExpr::to_expr(&false)
};
} else {
cmp_eq_body = quote_spanned! {span=>
#(#fields_cmp_eq)&*
};
cmp_ne_body = quote_spanned! {span=>
#(#fields_cmp_ne)|*
};
};
quote_spanned! {span=>
#[automatically_derived]
impl #impl_generics ::fayalite::expr::ops::ExprPartialEq<Self> for #target #type_generics
#where_clause
{
fn cmp_eq(
__lhs: ::fayalite::expr::Expr<Self>,
__rhs: ::fayalite::expr::Expr<Self>,
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
#cmp_eq_body
}
fn cmp_ne(
__lhs: ::fayalite::expr::Expr<Self>,
__rhs: ::fayalite::expr::Expr<Self>,
) -> ::fayalite::expr::Expr<::fayalite::int::Bool> {
#cmp_ne_body
}
}
}
.to_tokens(tokens);
}
if let (None, MaybeParsed::Parsed(generics)) = (no_static, &self.generics) {
let static_generics = generics.clone().for_static_type();
let (static_impl_generics, static_type_generics, static_where_clause) =