der/tag/class.rs
1//! Class of an ASN.1 tag.
2
3use super::{TagNumber, CONSTRUCTED_FLAG};
4use core::fmt;
5
6/// Class of an ASN.1 tag.
7#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
8#[repr(u8)]
9pub enum Class {
10 /// `UNIVERSAL`: built-in types whose meaning is the same in all
11 /// applications.
12 Universal = 0b00000000,
13
14 /// `APPLICATION`: types whose meaning is specific to an application,
15 ///
16 /// Types in two different applications may have the same
17 /// application-specific tag and different meanings.
18 Application = 0b01000000,
19
20 /// `CONTEXT-SPECIFIC`: types whose meaning is specific to a given
21 /// structured type.
22 ///
23 /// Context-specific tags are used to distinguish between component types
24 /// with the same underlying tag within the context of a given structured
25 /// type, and component types in two different structured types may have
26 /// the same tag and different meanings.
27 ContextSpecific = 0b10000000,
28
29 /// `PRIVATE`: types whose meaning is specific to a given enterprise.
30 Private = 0b11000000,
31}
32
33impl Class {
34 /// Compute the identifier octet for a tag number of this class.
35 #[allow(clippy::integer_arithmetic)]
36 pub(super) fn octet(self, constructed: bool, number: TagNumber) -> u8 {
37 self as u8 | number.value() | (u8::from(constructed) * CONSTRUCTED_FLAG)
38 }
39}
40
41impl fmt::Display for Class {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 f.write_str(match self {
44 Class::Universal => "UNIVERSAL",
45 Class::Application => "APPLICATION",
46 Class::ContextSpecific => "CONTEXT-SPECIFIC",
47 Class::Private => "PRIVATE",
48 })
49 }
50}