Skip to main content

codama_attributes/codama_directives/
export_directive.rs

1use crate::{Attribute, CodamaAttribute, CodamaDirective};
2use codama_errors::CodamaError;
3use codama_syn_helpers::{extensions::*, Meta};
4
5#[derive(Debug, PartialEq)]
6pub struct ExportDirective {
7    pub derive: String,
8}
9
10impl ExportDirective {
11    pub fn parse(meta: &Meta) -> syn::Result<Self> {
12        let pl = meta
13            .assert_directive("export")?
14            .as_path_list()
15            .map_err(|_| {
16                meta.error("export expects a single derive name — e.g. `export(CodamaType)`")
17            })?;
18        let metas = pl.parse_metas()?;
19        let [arg] = metas.as_slice() else {
20            return Err(
21                meta.error("export expects a single derive name — e.g. `export(CodamaType)`")
22            );
23        };
24        let derive = arg.as_path()?.last_str();
25        match derive.as_str() {
26            "CodamaAccount" | "CodamaAccounts" | "CodamaErrors" | "CodamaEvent"
27            | "CodamaEvents" | "CodamaInstruction" | "CodamaInstructions" | "CodamaPda"
28            | "CodamaType" => Ok(Self { derive }),
29            _ => Err(arg.error("unrecognized codama derive")),
30        }
31    }
32}
33
34impl<'a> TryFrom<&'a CodamaAttribute<'a>> for &'a ExportDirective {
35    type Error = CodamaError;
36
37    fn try_from(attribute: &'a CodamaAttribute) -> Result<Self, Self::Error> {
38        match attribute.directive.as_ref() {
39            CodamaDirective::Export(ref a) => Ok(a),
40            _ => Err(CodamaError::InvalidCodamaDirective {
41                expected: "export".to_string(),
42                actual: attribute.directive.name().to_string(),
43            }),
44        }
45    }
46}
47
48impl<'a> TryFrom<&'a Attribute<'a>> for &'a ExportDirective {
49    type Error = CodamaError;
50
51    fn try_from(attribute: &'a Attribute) -> Result<Self, Self::Error> {
52        <&CodamaAttribute>::try_from(attribute)?.try_into()
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn ok() {
62        let meta: Meta = syn::parse_quote! { export(CodamaType) };
63        let directive = ExportDirective::parse(&meta).unwrap();
64        assert_eq!(
65            directive,
66            ExportDirective {
67                derive: "CodamaType".to_string()
68            }
69        );
70    }
71
72    #[test]
73    fn fail_without_derive_name() {
74        let meta: Meta = syn::parse_quote! { export };
75        let error = ExportDirective::parse(&meta).unwrap_err();
76        assert_eq!(
77            error.to_string(),
78            "export expects a single derive name — e.g. `export(CodamaType)`"
79        );
80    }
81
82    #[test]
83    fn fail_with_unrecognized_derive() {
84        let meta: Meta = syn::parse_quote! { export(NotADerive) };
85        let error = ExportDirective::parse(&meta).unwrap_err();
86        assert_eq!(error.to_string(), "unrecognized codama derive");
87    }
88}