codama_attributes/codama_directives/
export_directive.rs1use 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}