asn1_rs_derive/
sequence.rs

1use crate::container::*;
2use proc_macro2::Span;
3use quote::quote;
4use syn::{Data, Ident, WherePredicate};
5
6pub fn derive_ber_sequence(s: synstructure::Structure) -> proc_macro2::TokenStream {
7    let ast = s.ast();
8
9    let container = match &ast.data {
10        Data::Struct(ds) => Container::from_datastruct(ds, ast, ContainerType::Sequence),
11        _ => panic!("Unsupported type, cannot derive"),
12    };
13
14    let debug_derive = ast.attrs.iter().any(|attr| {
15        attr.meta
16            .path()
17            .is_ident(&Ident::new("debug_derive", Span::call_site()))
18    });
19
20    let impl_tryfrom = container.gen_tryfrom();
21    let impl_tagged = container.gen_tagged();
22    let ts = s.gen_impl(quote! {
23        extern crate asn1_rs;
24
25        #impl_tryfrom
26        #impl_tagged
27    });
28    if debug_derive {
29        eprintln!("{}", ts);
30    }
31    ts
32}
33
34pub fn derive_der_sequence(s: synstructure::Structure) -> proc_macro2::TokenStream {
35    let ast = s.ast();
36
37    let container = match &ast.data {
38        Data::Struct(ds) => Container::from_datastruct(ds, ast, ContainerType::Sequence),
39        _ => panic!("Unsupported type, cannot derive"),
40    };
41
42    let debug_derive = ast.attrs.iter().any(|attr| {
43        attr.meta
44            .path()
45            .is_ident(&Ident::new("debug_derive", Span::call_site()))
46    });
47    let impl_tryfrom = container.gen_tryfrom();
48    let impl_tagged = container.gen_tagged();
49    let impl_checkconstraints = container.gen_checkconstraints();
50    let impl_fromder = container.gen_fromder();
51    let ts = s.gen_impl(quote! {
52        extern crate asn1_rs;
53
54        #impl_tryfrom
55        #impl_tagged
56        #impl_checkconstraints
57        #impl_fromder
58    });
59    if debug_derive {
60        eprintln!("{}", ts);
61    }
62    ts
63}
64
65pub fn derive_toder_sequence(s: synstructure::Structure) -> proc_macro2::TokenStream {
66    let ast = s.ast();
67
68    let container = match &ast.data {
69        Data::Struct(ds) => Container::from_datastruct(ds, ast, ContainerType::Sequence),
70        _ => panic!("Unsupported type, cannot derive"),
71    };
72
73    let debug_derive = ast.attrs.iter().any(|attr| {
74        attr.meta
75            .path()
76            .is_ident(&Ident::new("debug_derive", Span::call_site()))
77    });
78
79    //let lifetime = Lifetime::new("'ber", Span::call_site());
80    let wh = &container.where_predicates;
81    // we must filter out the 'ber lifetime (added for parsers, but not used here)
82    let wh = wh.iter().filter(|predicate| match predicate {
83        WherePredicate::Lifetime(lft) => lft.lifetime.ident != "ber",
84        _ => true,
85    });
86
87    let impl_to_der_len = container.gen_to_der_len();
88    let impl_write_der_header = container.gen_write_der_header();
89    let impl_write_der_content = container.gen_write_der_content();
90
91    // note: `gen impl` in synstructure takes care of appending extra where clauses if any, and removing
92    // the `where` statement if there are none.
93    let ts = s.gen_impl(quote! {
94        extern crate asn1_rs;
95
96        #[cfg(feature = "std")]
97        gen impl asn1_rs::ToDer for @Self where #(#wh)+* {
98            #impl_to_der_len
99            #impl_write_der_header
100            #impl_write_der_content
101        }
102    });
103    if debug_derive {
104        eprintln!("{}", ts);
105    }
106    ts
107}