use crate::{
parse::{
self,
attr::{self, ErrorLocation},
into_crate_root, into_transformation,
tuple_struct_field_impl::parse_tuple_struct_field,
AtMostOne, Attribute, CrateRoot, ProvideExpression, SourceFrom, SynErrors,
},
TupleStructInfo,
};
struct Attributes {
crate_root: Option<CrateRoot>,
provide_expressions: Vec<ProvideExpression>,
source_from: Option<SourceFrom>,
}
impl Attributes {
fn from_syn(attrs: &[syn::Attribute]) -> syn::Result<Self> {
let location = ErrorLocation::OnTupleStruct;
let mut errors = SynErrors::default();
let mut crate_roots = AtMostOne::attribute(attr::CrateRoot, location);
let mut provide_expressions = Vec::new();
let mut source_froms = AtMostOne::attribute(attr::SourceFrom, location);
parse::syn_attrs(attrs, &mut errors, |errors, attr| {
use Attribute::*;
match attr {
Backtrace(a) => errors.push_invalid_flag(a, location),
ContextFlag(a) => errors.push_invalid_flag(a, location),
ContextName(a) => errors.push_invalid(a, location),
ContextSuffix(a) => errors.push_invalid(a, location),
CrateRoot(a) => crate_roots.push(a),
Display(a) => errors.push_invalid(a, location),
DocComment(_a) => { }
Implicit(a) => errors.push_invalid_flag(a, location),
Module(a) => errors.push_invalid(a, location),
ProvideFlag(a) => errors.push_invalid_flag(a, location),
ProvideExpression(a) => provide_expressions.push(a),
SourceFlag(a) => errors.push_invalid_flag(a, location),
SourceFrom(a) => source_froms.push(a),
Transparent(a) => errors.push_invalid_flag(a, location),
Visibility(a) => errors.push_invalid(a, location),
Whatever(a) => errors.push_invalid(a, location),
}
});
let crate_root = crate_roots.finish_default(&mut errors);
let source_from = source_froms.finish_default(&mut errors);
errors.finish(Self {
crate_root,
provide_expressions,
source_from,
})
}
}
pub(crate) fn parse_tuple_struct(
fields: &syn::FieldsUnnamed,
name: &syn::Ident,
generics: &syn::Generics,
attrs: &[syn::Attribute],
span: impl quote::ToTokens,
) -> syn::Result<TupleStructInfo> {
let attrs = Attributes::from_syn(attrs);
let field_ty = parse_tuple_struct_field(fields, span);
let (attrs, field_ty) = join_syn_error!(attrs, field_ty)?;
let Attributes {
crate_root,
provide_expressions,
source_from,
} = attrs;
let crate_root = into_crate_root(crate_root);
let generics = generics.clone();
let name = name.clone();
let provides = provide_expressions
.into_iter()
.map(|p| p.into_provide())
.collect();
let transformation = into_transformation(source_from, field_ty, true);
Ok(TupleStructInfo {
crate_root,
generics,
name,
provides,
transformation,
})
}