asn1_compiler/generator/asn/types/
int.rs

1//! Handling top level Generator code for a Resolved Type. Based on the individual type variant,
2//! the respective functions are called.
3
4use 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        // FIXME: This is perhaps not right
93        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}