der/tag/class.rs
1//! Class of an ASN.1 tag.
2
3use core::fmt;
4
5/// `UNIVERSAL`: built-in types whose meaning is the same in all
6/// applications.
7pub const CLASS_UNIVERSAL: u8 = 0b00000000;
8/// `APPLICATION`: types whose meaning is specific to an application.
9pub const CLASS_APPLICATION: u8 = 0b01000000;
10/// `CONTEXT-SPECIFIC`: types whose meaning is specific to a given
11/// structured type.
12pub const CLASS_CONTEXT_SPECIFIC: u8 = 0b10000000;
13/// `PRIVATE`: types whose meaning is specific to a given enterprise.
14pub const CLASS_PRIVATE: u8 = 0b11000000;
15
16/// Class of an ASN.1 tag.
17#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
18#[repr(u8)]
19pub enum Class {
20 /// `UNIVERSAL`: built-in types whose meaning is the same in all
21 /// applications.
22 Universal = CLASS_UNIVERSAL,
23
24 /// `APPLICATION`: types whose meaning is specific to an application,
25 ///
26 /// Types in two different applications may have the same
27 /// application-specific tag and different meanings.
28 Application = CLASS_APPLICATION,
29
30 /// `CONTEXT-SPECIFIC`: types whose meaning is specific to a given
31 /// structured type.
32 ///
33 /// Context-specific tags are used to distinguish between component types
34 /// with the same underlying tag within the context of a given structured
35 /// type, and component types in two different structured types may have
36 /// the same tag and different meanings.
37 ContextSpecific = CLASS_CONTEXT_SPECIFIC,
38
39 /// `PRIVATE`: types whose meaning is specific to a given enterprise.
40 Private = CLASS_PRIVATE,
41}
42
43impl fmt::Display for Class {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 f.write_str(match self {
46 Class::Universal => "UNIVERSAL",
47 Class::Application => "APPLICATION",
48 Class::ContextSpecific => "CONTEXT-SPECIFIC",
49 Class::Private => "PRIVATE",
50 })
51 }
52}
53
54impl Class {
55 /// Returns class as 2 most-significant bits (mask 0b11000000)
56 #[must_use]
57 pub const fn bits(&self) -> u8 {
58 *self as u8
59 }
60
61 /// Returns class extracted from 2 most-significant bits (mask 0b11000000)
62 #[must_use]
63 pub const fn from_bits(bits: u8) -> Self {
64 match (bits >> 6) & 0b11 {
65 0b00 => Class::Universal,
66 0b01 => Class::Application,
67 0b10 => Class::ContextSpecific,
68 0b11 => Class::Private,
69 _ => unreachable!(),
70 }
71 }
72}
73impl From<u8> for Class {
74 fn from(value: u8) -> Self {
75 Class::from_bits(value)
76 }
77}