| 84 | } |
| 85 | |
| 86 | fn make_body(s: &Structure, accept: &syn::Ident, wc: &mut WhereCollector, use_try_visit: bool) -> TokenStream { |
| 87 | match &s.ast().data { |
| 88 | Data::Struct(ds) => { |
| 89 | let steps: Vec<TokenStream> = ds |
| 90 | .fields |
| 91 | .views() |
| 92 | .into_iter() |
| 93 | .zip(ds.fields.iter()) |
| 94 | .filter_map(|(view, syn_field)| { |
| 95 | if VisitStyle::from(syn_field.attrs.as_slice()) == VisitStyle::Skip { |
| 96 | return None; |
| 97 | } |
| 98 | wc.add(&syn_field.ty); |
| 99 | let m = &view.member; |
| 100 | if use_try_visit { |
| 101 | Some(quote! { visit_flow::try_visit!(self.#m.#accept(v)); }) |
| 102 | } else { |
| 103 | Some(quote! { self.#m.#accept(v); }) |
| 104 | } |
| 105 | }) |
| 106 | .collect(); |
| 107 | if use_try_visit { |
| 108 | quote! { #(#steps)* <visit_flow::VisitFlow as visit_flow::VisitFlowExt>::DESCEND } |
| 109 | } else { |
| 110 | quote! { #(#steps)* } |
| 111 | } |
| 112 | } |
| 113 | Data::Enum(_) => { |
| 114 | let arms: TokenStream = s |
| 115 | .variants() |
| 116 | .iter() |
| 117 | .map(|variant| { |
| 118 | let var_ident = variant.ast().ident; |
| 119 | let skip_variant = VisitStyle::from(variant.ast().attrs) == VisitStyle::Skip; |
| 120 | let bindings: Vec<_> = variant.bindings().iter().collect(); |
| 121 | let named = bindings.first().and_then(|bi| bi.ast().ident.as_ref()).is_some(); |
| 122 | |
| 123 | let (patterns, calls): (Vec<TokenStream>, Vec<TokenStream>) = bindings |
| 124 | .iter() |
| 125 | .map(|bi| { |
| 126 | let skip_field = |
| 127 | skip_variant || VisitStyle::from(bi.ast().attrs.as_slice()) == VisitStyle::Skip; |
| 128 | let binding = &bi.binding; |
| 129 | if named { |
| 130 | let field_name = bi.ast().ident.as_ref().unwrap(); |
| 131 | if skip_field { |
| 132 | (quote! { #field_name: _ }, quote! {}) |
| 133 | } else { |
| 134 | wc.add(&bi.ast().ty); |
| 135 | let call = if use_try_visit { |
| 136 | quote! { visit_flow::try_visit!(#binding.#accept(v)) } |
| 137 | } else { |
| 138 | quote! { #binding.#accept(v) } |
| 139 | }; |
| 140 | (quote! { #field_name: #binding }, call) |
| 141 | } |
| 142 | } else if skip_field { |
| 143 | (quote! { _ }, quote! {}) |