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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
use super::Tag;
use crate::{Error, ErrorKind, Result};
use core::fmt;
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct TagNumber(pub(super) u8);
impl TagNumber {
pub const N0: Self = Self(0);
pub const N1: Self = Self(1);
pub const N2: Self = Self(2);
pub const N3: Self = Self(3);
pub const N4: Self = Self(4);
pub const N5: Self = Self(5);
pub const N6: Self = Self(6);
pub const N7: Self = Self(7);
pub const N8: Self = Self(8);
pub const N9: Self = Self(9);
pub const N10: Self = Self(10);
pub const N11: Self = Self(11);
pub const N12: Self = Self(12);
pub const N13: Self = Self(13);
pub const N14: Self = Self(14);
pub const N15: Self = Self(15);
pub const N16: Self = Self(16);
pub const N17: Self = Self(17);
pub const N18: Self = Self(18);
pub const N19: Self = Self(19);
pub const N20: Self = Self(20);
pub const N21: Self = Self(21);
pub const N22: Self = Self(22);
pub const N23: Self = Self(23);
pub const N24: Self = Self(24);
pub const N25: Self = Self(25);
pub const N26: Self = Self(26);
pub const N27: Self = Self(27);
pub const N28: Self = Self(28);
pub const N29: Self = Self(29);
pub const N30: Self = Self(30);
pub(super) const MASK: u8 = 0b11111;
const MAX: u8 = 30;
#[allow(clippy::no_effect)]
pub const fn new(byte: u8) -> Self {
["tag number out of range"][(byte > Self::MAX) as usize];
Self(byte)
}
pub fn application(self, constructed: bool) -> Tag {
Tag::Application {
constructed,
number: self,
}
}
pub fn context_specific(self, constructed: bool) -> Tag {
Tag::ContextSpecific {
constructed,
number: self,
}
}
pub fn private(self, constructed: bool) -> Tag {
Tag::Private {
constructed,
number: self,
}
}
pub fn value(self) -> u8 {
self.0
}
}
impl TryFrom<u8> for TagNumber {
type Error = Error;
fn try_from(byte: u8) -> Result<Self> {
match byte {
0..=Self::MAX => Ok(Self(byte)),
_ => Err(ErrorKind::TagNumberInvalid.into()),
}
}
}
impl From<TagNumber> for u8 {
fn from(tag_number: TagNumber) -> u8 {
tag_number.0
}
}
impl fmt::Display for TagNumber {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}