asn1_compiler/generator/asn/types/
int.rs1use proc_macro2::{Ident, TokenStream};
5use quote::quote;
6
7use crate::generator::Generator;
8use crate::resolver::asn::structs::types::{Asn1ResolvedType, ResolvedSetType};
9use anyhow::Result;
10
11impl Asn1ResolvedType {
12 pub(crate) fn generate_for_type(
13 name: &str,
14 ty: &Asn1ResolvedType,
15 gen: &mut Generator,
16 ) -> Result<Option<TokenStream>> {
17 match ty {
18 Asn1ResolvedType::Base(ref b) => Ok(Some(b.generate_for_base_type(name, gen)?)),
19 Asn1ResolvedType::Constructed(ref c) => Ok(Some(c.generate(name, gen)?)),
20 Asn1ResolvedType::Set(ref s) => Ok(Some(s.generate(name, gen)?)),
21 Asn1ResolvedType::Reference(ref reference) => Ok(Some(
22 Asn1ResolvedType::generate_type_alias_for_reference(name, gen, reference)?,
23 )),
24 }
25 }
26
27 pub(crate) fn generate_name_maybe_aux_type(
28 ty: &Asn1ResolvedType,
29 generator: &mut Generator,
30 input: Option<&String>,
31 ) -> Result<Ident> {
32 match ty {
33 Asn1ResolvedType::Base(ref b) => {
34 b.generate_ident_and_aux_type_for_base(generator, input)
35 }
36 Asn1ResolvedType::Reference(ref r) => {
37 Asn1ResolvedType::generate_ident_for_reference(r, generator)
38 }
39 Asn1ResolvedType::Constructed(ref c) => {
40 c.generate_ident_and_aux_type_for_constucted(generator, input)
41 }
42 Asn1ResolvedType::Set(ref s) => {
43 s.generate_ident_and_aux_types_for_set(generator, input)
44 }
45 }
46 }
47
48 pub(crate) fn generate_ident_for_reference(
49 reference: &str,
50 gen: &mut Generator,
51 ) -> Result<Ident> {
52 Ok(gen.to_type_ident(reference))
53 }
54
55 fn generate_type_alias_for_reference(
56 name: &str,
57 gen: &mut Generator,
58 reference: &str,
59 ) -> Result<TokenStream> {
60 let referring = gen.to_type_ident(name);
61 let reference = gen.to_type_ident(reference);
62
63 let vis = gen.get_visibility_tokens();
64
65 Ok(quote! {
66 #vis type #referring = #reference;
67 })
68 }
69}
70
71impl ResolvedSetType {
72 pub(crate) fn generate(&self, name: &str, generator: &mut Generator) -> Result<TokenStream> {
73 let ty_ident = generator.to_type_ident(name);
74 let ty_elements = self.generate_aux_types(generator)?;
75
76 let vis = generator.get_visibility_tokens();
77 let dir = generator.generate_derive_tokens();
78
79 Ok(quote! {
80 #dir
81 #vis enum #ty_ident {
82 #ty_elements
83 }
84 })
85 }
86
87 pub(crate) fn generate_ident_and_aux_types_for_set(
88 &self,
89 generator: &mut Generator,
90 input: Option<&String>,
91 ) -> Result<Ident> {
92 let ty_ident = match input {
94 None => generator.to_type_ident(&self.setref),
95 Some(inp) => generator.to_type_ident(inp),
96 };
97 let ty_elements = self.generate_aux_types(generator)?;
98
99 let vis = generator.get_visibility_tokens();
100 let dir = generator.generate_derive_tokens();
101
102 let set_ty = quote! {
103 #dir
104 #[asn(type = "OPEN")]
105 #vis enum #ty_ident {
106 #ty_elements
107 }
108 };
109
110 generator.aux_items.push(set_ty);
111
112 Ok(ty_ident)
113 }
114
115 fn generate_aux_types(&self, generator: &mut Generator) -> Result<TokenStream> {
116 let mut variant_tokens = TokenStream::new();
117 for (name, ty) in &self.types {
118 let variant_ident = generator.to_type_ident(&name.0);
119 let ty_ident =
120 Asn1ResolvedType::generate_name_maybe_aux_type(&ty.1, generator, Some(&name.0))?;
121 let key: proc_macro2::TokenStream = ty.0.to_string().parse().unwrap();
122 let key_tokens = quote! {
123 #[asn(key = #key)]
124 };
125
126 let variant_token = quote! {
127 #key_tokens
128 #variant_ident(#ty_ident),
129 };
130 variant_tokens.extend(variant_token);
131 }
132 Ok(variant_tokens)
133 }
134}