codama_attributes/
attribute.rs

1use crate::{
2    AttributeContext, CodamaAttribute, DeriveAttribute, ReprAttribute, UnsupportedAttribute,
3};
4use codama_syn_helpers::extensions::*;
5use derive_more::derive::From;
6
7#[derive(Debug, PartialEq, From)]
8pub enum Attribute<'a> {
9    // E.g. `#[codama(type = number(u8))]` or `#[codama(fixed_size = 32)]`.
10    Codama(CodamaAttribute<'a>),
11    // E.g. `#[derive(Debug, CodamaType)]`.
12    Derive(DeriveAttribute<'a>),
13    // E.g. `#[repr(u32, align(8))]`.
14    Repr(ReprAttribute<'a>),
15    // E.g. `#[some_unsupported_attribute = 42]`.
16    Unsupported(UnsupportedAttribute<'a>),
17}
18
19impl<'a> Attribute<'a> {
20    pub fn parse(ast: &'a syn::Attribute, ctx: &AttributeContext) -> syn::Result<Self> {
21        // Check if the attribute is feature-gated.
22        let unfeatured = ast.unfeatured();
23        let attr = unfeatured.as_ref().unwrap_or(ast);
24
25        let path = attr.path();
26        match (path.prefix().as_str(), path.last_str().as_str()) {
27            ("" | "codama_macros" | "codama", "codama") => {
28                Ok(CodamaAttribute::parse(ast, ctx)?.into())
29            }
30            ("", "derive") => Ok(DeriveAttribute::parse(ast)?.into()),
31            ("", "repr") => Ok(ReprAttribute::parse(ast)?.into()),
32            _ => Ok(UnsupportedAttribute::new(ast).into()),
33        }
34    }
35
36    pub fn ast(&self) -> &syn::Attribute {
37        match self {
38            Attribute::Codama(a) => a.ast,
39            Attribute::Derive(a) => a.ast,
40            Attribute::Repr(a) => a.ast,
41            Attribute::Unsupported(a) => a.ast,
42        }
43    }
44
45    pub fn name(&self) -> String {
46        self.ast().path().last_str()
47    }
48}