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