MCPcopy Create free account
hub / github.com/csskit/csskit / derive

Function derive

crates/csskit_derives/src/semantic_eq.rs:18–101  ·  view source on GitHub ↗
(input: DeriveInput)

Source from the content-addressed store, hash-verified

16}
17
18pub fn derive(input: DeriveInput) -> Result<TokenStream> {
19 if let Data::Struct(ref s) = input.data
20 && matches!(s.fields, Fields::Unit)
21 {
22 return Err(Error::new(input.ident.span(), "Cannot derive SemanticEq on this struct"));
23 }
24 if matches!(input.data, Data::Union(_)) {
25 return Err(Error::new(input.ident.span(), "Cannot derive SemanticEq on a Union"));
26 }
27
28 let s_a = structure_with_prefix(&input, "a")?;
29 let s_b = structure_with_prefix(&input, "b")?;
30
31 let mut wc = WhereCollector::new();
32 for variant in s_a.variants() {
33 for bi in variant.bindings() {
34 wc.add(&bi.ast().ty);
35 }
36 }
37
38 let ident = &input.ident;
39 let (impl_generics, type_generics, _) = input.generics.split_for_impl();
40
41 let body = if matches!(input.data, Data::Struct(_)) {
42 let steps: Vec<TokenStream> = s_a.variants()[0]
43 .bindings()
44 .iter()
45 .zip(s_b.variants()[0].bindings().iter())
46 .map(|(a, b)| {
47 let a_name = &a.binding;
48 let b_name = &b.binding;
49 quote! { #a_name.semantic_eq(&#b_name) }
50 })
51 .collect();
52 let a_pat = s_a.variants()[0].pat();
53 let b_pat = s_b.variants()[0].pat();
54 let body = steps.into_iter().reduce(|acc, item| quote! { #acc && #item }).unwrap_or_default();
55 quote! {
56 let #a_pat = self;
57 let #b_pat = other;
58 #body
59 }
60 } else {
61 let arms: TokenStream = s_a
62 .variants()
63 .iter()
64 .zip(s_b.variants().iter())
65 .map(|(va, vb)| {
66 let a_pat = va.pat();
67 let b_pat = vb.pat();
68 let steps: Vec<TokenStream> = va
69 .bindings()
70 .iter()
71 .zip(vb.bindings().iter())
72 .map(|(a, b)| {
73 let a_name = &a.binding;
74 let b_name = &b.binding;
75 quote! { #a_name.semantic_eq(&#b_name) }

Callers

nothing calls this directly

Calls 9

ErrClass · 0.85
structure_with_prefixFunction · 0.85
astMethod · 0.80
collectMethod · 0.80
iterMethod · 0.80
into_iterMethod · 0.80
extend_where_clauseMethod · 0.80
spanMethod · 0.45
addMethod · 0.45

Tested by

no test coverage detected