1#[macro_use]
2extern crate quote;
3
4mod asn_type;
5mod config;
6mod decode;
7mod encode;
8mod r#enum;
9mod ext;
10mod tag;
11
12use crate::ext::GenericsExt;
13use config::Config;
14use syn::{DataStruct, DeriveInput};
15
16const CRATE_NAME: &str = "rasn";
17
18pub fn decode_derive_inner(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
19 let config = Config::from_attributes(&input)?;
20 let name = &input.ident;
21 let mut generics = input.generics;
22 let crate_root = &config.crate_root;
23 generics.add_trait_bounds(crate_root, quote::format_ident!("Decode"));
24
25 match input.data {
26 syn::Data::Struct(DataStruct {
28 fields: syn::Fields::Unit,
29 ..
30 }) => Ok(quote! {
31 impl #crate_root::Decode for #name {
32 fn decode_with_tag_and_constraints<D: #crate_root::Decoder>(
33 decoder: &mut D,
34 tag: #crate_root::types::Tag,
35 _: #crate_root::prelude::Constraints,
36 ) -> Result<Self, D::Error> {
37 decoder.decode_null(tag).map(|_| #name)
38 }
39 }
40 }),
41 syn::Data::Struct(v) => decode::derive_struct_impl(name, generics, v, &config),
42 syn::Data::Enum(syn::DataEnum { variants, .. }) => r#enum::Enum {
43 name,
44 generics: &generics,
45 variants: &variants,
46 config: &config,
47 }
48 .impl_decode(),
49 _ => Err(syn::Error::new(
50 name.span(),
51 "Union types are not supported.",
52 )),
53 }
54}
55
56pub fn encode_derive_inner(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
57 let config = Config::from_attributes(&input)?;
58 let name = &input.ident;
59 let mut generics = input.generics;
60 let crate_root = &config.crate_root;
61 generics.add_trait_bounds(crate_root, quote::format_ident!("Encode"));
62
63 Ok(match input.data {
64 syn::Data::Struct(DataStruct {
66 fields: syn::Fields::Unit,
67 ..
68 }) => quote! {
69 impl #crate_root::Encode for #name {
70 fn encode_with_tag_and_constraints<'encoder, E: #crate_root::Encoder<'encoder>>(
71 &self,
72 encoder: &mut E,
73 tag: #crate_root::types::Tag,
74 constraints: #crate_root::prelude::Constraints,
75 identifier: #crate_root::types::Identifier,
76 ) -> Result<(), E::Error> {
77 encoder.encode_null(tag, identifier).map(drop)
78 }
79 }
80 },
81 syn::Data::Struct(v) => encode::derive_struct_impl(name, generics, v, &config)?,
82 syn::Data::Enum(syn::DataEnum { variants, .. }) => r#enum::Enum {
83 name,
84 generics: &generics,
85 variants: &variants,
86 config: &config,
87 }
88 .impl_encode()?,
89 _ => {
90 return Err(syn::Error::new(
91 name.span(),
92 "Union types are not supported.",
93 ));
94 }
95 })
96}
97
98pub fn asn_type_derive_inner(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
99 let config = Config::from_attributes(&input)?;
100 let name = &input.ident;
101 let mut generics = input.generics;
102 let crate_root = &config.crate_root;
103 for param in &mut generics.params {
104 if let syn::GenericParam::Type(type_param) = param {
105 type_param
106 .bounds
107 .push(syn::parse_quote!(#crate_root::AsnType));
108 }
109 }
110
111 Ok(match input.data {
112 syn::Data::Struct(v) => asn_type::derive_struct_impl(name, generics, v, &config)?,
113 syn::Data::Enum(syn::DataEnum { variants, .. }) => r#enum::Enum {
114 name,
115 generics: &generics,
116 variants: &variants,
117 config: &config,
118 }
119 .impl_asntype()?,
120 _ => {
121 return Err(syn::Error::new(
122 name.span(),
123 "Union types are not supported.",
124 ));
125 }
126 })
127}