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,
})
}