fn extract()

in shed/facet/proc_macros/container_impl.rs [30:130]


    fn extract(container: &mut ItemStruct) -> Result<Self, Error> {
        let mut field_idents = Vec::new();
        let mut field_inits = Vec::new();
        let mut facet_idents = Vec::new();
        let mut facet_types = Vec::new();
        let mut delegate_idents = Vec::new();
        let mut delegate_types = Vec::new();
        let mut delegate_facets = Vec::new();
        match &mut container.fields {
            Fields::Named(named_fields) => {
                for field in named_fields.named.iter_mut() {
                    let mut attr_found = false;
                    let mut new_attrs = Vec::new();
                    for attr in field.attrs.drain(..) {
                        if attr.path.is_ident("init") {
                            if attr_found {
                                return Err(Error::new(
                                    attr.span(),
                                    concat!(
                                        "facet::container field must have exactly one ",
                                        "of 'init', 'facet' or 'delegate', found multiple"
                                    ),
                                ));
                            }
                            attr_found = true;
                            let expr: Expr = attr.parse_args()?;
                            field_idents
                                .push(field.ident.clone().expect("named field must have a name"));
                            field_inits.push(expr);
                        } else if attr.path.is_ident("facet") {
                            if attr_found {
                                return Err(Error::new(
                                    attr.span(),
                                    concat!(
                                        "facet::container field must have exactly one ",
                                        "of 'init', 'facet' or 'delegate', found multiple"
                                    ),
                                ));
                            }
                            attr_found = true;
                            let mut facet_type = field.ty.clone();
                            if let Type::TraitObject(obj) = &mut facet_type {
                                obj.bounds.push(syn::parse2(quote!(::std::marker::Send))?);
                                obj.bounds.push(syn::parse2(quote!(::std::marker::Sync))?);
                                obj.bounds.push(syn::parse2(quote!('static))?);
                            }
                            field.ty = syn::parse2(quote!(::std::sync::Arc<#facet_type>))?;
                            facet_idents
                                .push(field.ident.clone().expect("named field must have a name"));
                            facet_types.push(facet_type);
                        } else if attr.path.is_ident("delegate") {
                            if attr_found {
                                return Err(Error::new(
                                    attr.span(),
                                    concat!(
                                        "facet::container field must have exactly one ",
                                        "of 'init', 'facet' or 'delegate', found multiple"
                                    ),
                                ));
                            }
                            attr_found = true;
                            let delegate_type = field.ty.clone();
                            let facets = extract_delegate_facets(&attr)?;
                            delegate_idents
                                .push(field.ident.clone().expect("named field must have a name"));
                            delegate_types.push(delegate_type);
                            delegate_facets.push(facets);
                        } else {
                            new_attrs.push(attr);
                        }
                    }
                    if !attr_found {
                        return Err(Error::new(
                            field.span(),
                            concat!(
                                "facet::container field must have exactly one ",
                                "of 'init', 'facet' or 'delegate', found none"
                            ),
                        ));
                    }
                    field.attrs = new_attrs;
                }
            }
            _ => {
                return Err(Error::new(
                    container.ident.span(),
                    "facet::container requires a struct with named fields",
                ));
            }
        }

        Ok(ContainerMembers {
            field_idents,
            field_inits,
            facet_idents,
            facet_types,
            delegate_idents,
            delegate_types,
            delegate_facets,
        })
    }