Skip to main content

codama_attributes/codama_directives/
codama_directive.rs

1use crate::{
2    AccountDirective, ArgumentDirective, AttributeContext, DefaultValueDirective,
3    DiscriminatorDirective, DisplayDirective, EncodingDirective, EnumDiscriminatorDirective,
4    ErrorDirective, ExportDirective, FieldDirective, FixedSizeDirective, NameDirective,
5    OptionalAccountStrategyDirective, PdaDirective, ProgramDirective, RemainingAccountsDirective,
6    SeedDirective, SizePrefixDirective, SkipDirective, TypeDirective,
7};
8use codama_syn_helpers::{extensions::*, Meta};
9use derive_more::derive::From;
10
11#[derive(Debug, PartialEq, From)]
12pub enum CodamaDirective {
13    // Type directives.
14    Type(TypeDirective),
15    Encoding(EncodingDirective),
16    Field(FieldDirective),
17    FixedSize(FixedSizeDirective),
18    SizePrefix(SizePrefixDirective),
19
20    // Default value directive.
21    DefaultValue(DefaultValueDirective),
22
23    // Multi-purpose directives.
24    Discriminator(DiscriminatorDirective),
25    Display(DisplayDirective),
26    EnumDiscriminator(EnumDiscriminatorDirective),
27    Export(ExportDirective),
28    Name(NameDirective),
29    OptionalAccountStrategy(OptionalAccountStrategyDirective),
30    Program(ProgramDirective),
31    Seed(SeedDirective),
32    Skip(SkipDirective),
33
34    // Account directives.
35    Pda(PdaDirective),
36
37    // Instruction directives.
38    Account(AccountDirective),
39    Argument(ArgumentDirective),
40    RemainingAccounts(RemainingAccountsDirective),
41
42    // Error directives.
43    Error(ErrorDirective),
44}
45
46impl CodamaDirective {
47    pub fn parse(meta: &Meta, ctx: &AttributeContext) -> syn::Result<Self> {
48        let path = meta.path()?;
49        match path.to_string().as_str() {
50            // Type directives.
51            "type" => Ok(TypeDirective::parse(meta)?.into()),
52            "encoding" => Ok(EncodingDirective::parse(meta)?.into()),
53            "field" => Ok(FieldDirective::parse(meta)?.into()),
54            "fixed_size" => Ok(FixedSizeDirective::parse(meta)?.into()),
55            "size_prefix" => Ok(SizePrefixDirective::parse(meta)?.into()),
56
57            // Default value directive.
58            "default_value" => Ok(DefaultValueDirective::parse(meta)?.into()),
59            "value" => Ok(DefaultValueDirective::parse(meta)?.into()),
60
61            // Multi-purpose directives.
62            "discriminator" => Ok(DiscriminatorDirective::parse(meta)?.into()),
63            "display" => Ok(DisplayDirective::parse(meta)?.into()),
64            "enum_discriminator" => Ok(EnumDiscriminatorDirective::parse(meta)?.into()),
65            "export" => Ok(ExportDirective::parse(meta)?.into()),
66            "name" => Ok(NameDirective::parse(meta)?.into()),
67            "optional_account_strategy" => {
68                Ok(OptionalAccountStrategyDirective::parse(meta)?.into())
69            }
70            "program" => Ok(ProgramDirective::parse(meta)?.into()),
71            "seed" => Ok(SeedDirective::parse(meta, ctx)?.into()),
72            "skip" => Ok(SkipDirective::parse(meta)?.into()),
73
74            // Account directives.
75            "pda" => Ok(PdaDirective::parse(meta)?.into()),
76
77            // Instruction directives.
78            "account" => Ok(AccountDirective::parse(meta, ctx)?.into()),
79            "argument" => Ok(ArgumentDirective::parse(meta)?.into()),
80            "remaining_accounts" => Ok(RemainingAccountsDirective::parse(meta)?.into()),
81            "provide" => Err(path.error("provide directives are not supported yet")),
82
83            // Error directives.
84            "error" => Ok(ErrorDirective::parse(meta)?.into()),
85
86            _ => Err(path.error("unrecognized codama directive")),
87        }
88    }
89
90    pub fn name(&self) -> &'static str {
91        match self {
92            // Type directives.
93            Self::Type(_) => "type",
94            Self::Encoding(_) => "encoding",
95            Self::Field(_) => "field",
96            Self::FixedSize(_) => "fixed_size",
97            Self::SizePrefix(_) => "size_prefix",
98
99            // Default value directive.
100            Self::DefaultValue(_) => "default_value | value",
101
102            // Multi-purpose directives.
103            Self::Discriminator(_) => "discriminator",
104            Self::Display(_) => "display",
105            Self::EnumDiscriminator(_) => "enum_discriminator",
106            Self::Export(_) => "export",
107            Self::Name(_) => "name",
108            Self::OptionalAccountStrategy(_) => "optional_account_strategy",
109            Self::Program(_) => "program",
110            Self::Seed(_) => "seed",
111            Self::Skip(_) => "skip",
112
113            // Account directives.
114            Self::Pda(_) => "pda",
115
116            // Instruction directives.
117            Self::Account(_) => "account",
118            Self::Argument(_) => "argument",
119            Self::RemainingAccounts(_) => "remaining_accounts",
120
121            // Error directives.
122            Self::Error(_) => "error",
123        }
124    }
125}