dasn1_core/
identifier.rs

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    /// Instantiate a `Class` from a u8.
11    ///
12    /// # Panics
13    /// If `value` is greater than 3.
14    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/// An abstract representation of the identifier octets used in BER, CER, and
30/// DER to identify .
31#[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}