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(attr: &'a syn::Attribute, ctx: &AttributeContext) -> syn::Result<Self> {
21        let path = attr.path();
22        match (path.prefix().as_str(), path.last_str().as_str()) {
23            ("" | "codama_macros" | "codama", "codama") => {
24                Ok(CodamaAttribute::parse(attr, ctx)?.into())
25            }
26            ("", "derive") => Ok(DeriveAttribute::parse(attr)?.into()),
27            ("", "repr") => Ok(ReprAttribute::parse(attr)?.into()),
28            _ => Ok(UnsupportedAttribute::new(attr).into()),
29        }
30    }
31
32    pub fn ast(&self) -> &syn::Attribute {
33        match self {
34            Attribute::Codama(a) => a.ast,
35            Attribute::Derive(a) => a.ast,
36            Attribute::Repr(a) => a.ast,
37            Attribute::Unsupported(a) => a.ast,
38        }
39    }
40
41    pub fn name(&self) -> String {
42        self.ast().path().last_str()
43    }
44}