1#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
2pub enum Class {
3 Universal = 0,
4 Application,
5 Context,
6 Private,
7}
8
9impl Class {
10 pub fn from_u8(value: u8) -> Self {
15 match value {
16 0 => Class::Universal,
17 1 => Class::Application,
18 2 => Class::Context,
19 3 => Class::Private,
20 num => panic!("'{}' is not a valid class of tag.", num),
21 }
22 }
23
24 pub fn is_universal(self) -> bool {
25 self == Class::Universal
26 }
27}
28
29#[derive(Debug, Clone, Copy, Eq, PartialEq)]
32pub struct Identifier {
33 pub class: Class,
34 pub tag: u32,
35}
36
37macro_rules! consts {
38 ($($name:ident = $value:expr),+) => {
39 $(
40 pub const $name: Identifier = Identifier::new(Class::Universal, $value);
41 )+
42 }
43}
44
45impl Identifier {
46 consts! {
47 EOC = 0,
48 BOOL = 1,
49 INTEGER = 2,
50 BIT_STRING = 3,
51 OCTET_STRING = 4,
52 NULL = 5,
53 OBJECT_IDENTIFIER = 6,
54 OBJECT_DESCRIPTOR = 7,
55 EXTERNAL = 8,
56 REAL = 9,
57 ENUMERATED = 10,
58 EMBEDDED_PDV = 11,
59 UTF8_STRING = 12,
60 RELATIVE_OID = 13,
61 SEQUENCE = 16,
62 SET = 17,
63 NUMERIC_STRING = 18,
64 PRINTABLE_STRING = 19,
65 TELETEX_STRING = 20,
66 VIDEOTEX_STRING = 21,
67 IA5_STRING = 22,
68 UTC_TIME = 23,
69 GENERALIZED_TIME = 24,
70 GRAPHIC_STRING = 25,
71 VISIBLE_STRING = 26,
72 GENERAL_STRING = 27,
73 UNIVERSAL_STRING = 28,
74 CHARACTER_STRING = 29,
75 BMP_STRING = 30
76 }
77
78 pub const fn new(class: Class, tag: u32) -> Self {
79 Self {
80 class,
81 tag,
82 }
83 }
84
85 pub fn set_tag(mut self, tag: u32) -> Self {
86 self.tag = tag;
87 self
88 }
89
90 pub fn len(&self) -> usize {
91 if self.tag > 0x1f {
92 let mut len = 1;
93 let mut tag = self.tag;
94 while tag != 0 {
95 len += 1;
96 tag >>= 7;
97 }
98
99 len
100 } else {
101 1
102 }
103 }
104}
105
106pub mod constant {
107 pub trait Prefix: Copy + Clone + Ord + PartialOrd + Eq + PartialEq + std::fmt::Debug {
108 const NAME: &'static str;
109 }
110
111 pub trait ConstClass: Copy + Clone + Ord + PartialOrd + Eq + PartialEq + std::fmt::Debug {
112 const CLASS: super::Class;
113 }
114
115 macro_rules! classes {
116 ($($name:ident)+) => {
117 $(
118 #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
119 pub struct $name;
120
121 impl ConstClass for $name {
122 const CLASS: super::Class = super::Class::$name;
123 }
124 )+
125 }
126 }
127
128 classes!(Universal Application Context Private);
129
130
131 macro_rules! prefixes {
132 ($($name:ident = $value:expr),+) => {
133 $(
134 #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
135 pub struct $name;
136
137 impl Prefix for $name {
138 const NAME: &'static str = $value;
139 }
140 )+
141 }
142 }
143
144 prefixes! {
145 ImplicitPrefix = "ASN.1#Implicit",
146 ExplicitPrefix = "ASN.1#Explicit"
147 }
148}