Skip to main content

codama_attributes/codama_directives/
codama_directive.rs

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