use crate::Defs;
use macro_compose::{Collector, Context, Lint};
use syn::{Data, DeriveInput, Error, ItemStruct};
pub struct StructLint<'a> {
struct_defs: &'a Defs<'a>,
fields_defs: &'a Defs<'a>,
}
impl<'a> StructLint<'a> {
#[must_use]
pub const fn new(struct_defs: &'a Defs<'a>, fields_defs: &'a Defs<'a>) -> Self {
StructLint {
struct_defs,
fields_defs,
}
}
}
impl Lint<ItemStruct> for StructLint<'_> {
fn lint(&self, input: &ItemStruct, c: &mut Collector) {
let derive_input = DeriveInput::from(input.clone());
let mut subcontext = Context::new_by_ref(c, &derive_input);
subcontext.lint(self);
}
}
impl Lint<DeriveInput> for StructLint<'_> {
fn lint(&self, input: &DeriveInput, c: &mut Collector) {
let mut subcontext = Context::new_by_ref(c, &input.attrs);
subcontext.lint(self.struct_defs);
match &input.data {
Data::Struct(s) => {
for field in s.fields.iter() {
let mut subcontext = Context::new_by_ref(c, &field.attrs);
subcontext.lint(self.fields_defs);
}
}
_ => c.error(Error::new_spanned(input, "expected a struct")),
}
}
}