Skip to main content

codama_attributes/
attribute_context.rs

1use derive_more::derive::From;
2
3#[derive(Debug, PartialEq, From)]
4pub enum AttributeContext<'a> {
5    /// The root of a crate, i.e. the inner attributes of its `lib.rs`/`main.rs`.
6    ///
7    /// Distinct from [`AttributeContext::File`] (a file-module) because only the
8    /// crate root carries the primary program's default identity. Constructed
9    /// explicitly (never via `From`) so `From<&syn::File>` keeps mapping to
10    /// [`AttributeContext::File`].
11    #[from(skip)]
12    Crate(&'a syn::File),
13    /// A file-module, i.e. the inner attributes of a `mod foo;` living in its
14    /// own `foo.rs`.
15    File(&'a syn::File),
16    /// A top-level item, such as a `struct`, `enum` or inline `mod { .. }`.
17    Item(&'a syn::Item),
18    /// An enum variant.
19    Variant(&'a syn::Variant),
20    /// A field of a struct or an enum variant.
21    Field(&'a syn::Field),
22    /// An item within an `impl` block.
23    ImplItem(&'a syn::ImplItem),
24}
25
26impl<'a> AttributeContext<'a> {
27    pub fn get_fields(&self) -> Option<&'a syn::Fields> {
28        match self {
29            AttributeContext::Item(syn::Item::Struct(syn::ItemStruct { fields, .. })) => {
30                Some(fields)
31            }
32            AttributeContext::Variant(syn::Variant { fields, .. }) => Some(fields),
33            _ => None,
34        }
35    }
36
37    pub fn get_named_fields(&self) -> Option<&'a syn::FieldsNamed> {
38        match self.get_fields() {
39            Some(syn::Fields::Named(fields)) => Some(fields),
40            _ => None,
41        }
42    }
43}