mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Generalise compare_fields to work with iterators (#4823)
## Proposed Changes Add `compare_fields(as_iter)` as a field attribute to `compare_fields_derive`. This allows any iterable type to be compared in the same as a slice (by index). This is forwards-compatible with tree-states types like `List` and `Vector` which can not be cast to slices.
This commit is contained in:
@@ -4,10 +4,11 @@ use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, DeriveInput};
|
||||
|
||||
fn is_slice(field: &syn::Field) -> bool {
|
||||
fn is_iter(field: &syn::Field) -> bool {
|
||||
field.attrs.iter().any(|attr| {
|
||||
attr.path.is_ident("compare_fields")
|
||||
&& attr.tokens.to_string().replace(' ', "") == "(as_slice)"
|
||||
&& (attr.tokens.to_string().replace(' ', "") == "(as_slice)"
|
||||
|| attr.tokens.to_string().replace(' ', "") == "(as_iter)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,13 +35,13 @@ pub fn compare_fields_derive(input: TokenStream) -> TokenStream {
|
||||
let field_name = ident_a.to_string();
|
||||
let ident_b = ident_a.clone();
|
||||
|
||||
let quote = if is_slice(field) {
|
||||
let quote = if is_iter(field) {
|
||||
quote! {
|
||||
comparisons.push(compare_fields::Comparison::from_slice(
|
||||
comparisons.push(compare_fields::Comparison::from_into_iter(
|
||||
#field_name.to_string(),
|
||||
&self.#ident_a,
|
||||
&b.#ident_b)
|
||||
);
|
||||
&b.#ident_b
|
||||
));
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
|
||||
Reference in New Issue
Block a user