1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use tag;
pub trait Asn1Info {
fn asn1_tag() -> Option<tag::Tag>;
fn asn1_type() -> tag::Type;
}
#[macro_export]
macro_rules! asn1_info {
($rs_type:ty => $gen:ident, $($args:tt)*) => (
impl<$gen> $crate::Asn1Info for $rs_type {
asn1_info!{__impl $($args)*}
}
);
(__impl [$($args:tt)*], $asn1_ty:expr) => (
fn asn1_tag() -> Option<$crate::tag::Tag> {
Some(asn1_spec_tag!([$($args)*]))
}
asn1_info!(__type $asn1_ty);
);
(__impl $class:expr, $tagnum:expr, $constructed:expr, $asn1_ty:expr) => (
fn asn1_tag() -> Option<$crate::tag::Tag> {
Some($crate::tag::Tag {
class: ($class as u8).into(),
tagnum: $tagnum as $crate::tag::TagNum,
constructed: $constructed,
})
}
asn1_info!(__type $asn1_ty);
);
(__impl $asn1_ty:expr) => (
fn asn1_tag() -> Option<$crate::tag::Tag> {
None
}
asn1_info!(__type $asn1_ty);
);
(__type $asn1_ty:expr) => (
fn asn1_type() -> $crate::tag::Type {
$crate::tag::Type::from($asn1_ty)
}
);
($rs_type:ty, $($args:tt)*) => (
impl $crate::Asn1Info for $rs_type {
asn1_info!{__impl $($args)*}
}
);
}
#[macro_export]
macro_rules! asn1_spec_tag {
({ $count:ident }) => (
asn1_spec_tag!([])
);
({ $count:ident } []) => ({
let _count = $count;
$count += 1;
asn1_spec_tag!([CONTEXT _count])
});
({ $count:ident } [$($args:tt)*]) => (
asn1_spec_tag!([$($args)*])
);
([$tagnum:expr]) => (
asn1_spec_tag!([CONTEXT $tagnum]);
);
([UNIVERSAL $tagnum:expr]) => (
$crate::tag::Tag {
class: $crate::tag::Class::Universal,
tagnum: $tagnum,
constructed: true,
}
);
([CONTEXT $tagnum:expr]) => (
$crate::tag::Tag {
class: $crate::tag::Class::ContextSpecific,
tagnum: $tagnum,
constructed: true,
}
);
([APPLICATION $tagnum:expr]) => (
$crate::tag::Tag {
class: $crate::tag::Class::Application,
tagnum: $tagnum,
constructed: true,
}
);
([PRIVATE $tagnum:expr]) => (
$crate::tag::Tag {
class: $crate::tag::Class::Private,
tagnum: $tagnum,
constructed: true,
}
);
}