Skip to main content

codama_attributes/codama_directives/
codama_directive.rs

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