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
use crate::{Class, Error, Tag, Tagged};
use core::marker::PhantomData;
mod application;
mod builder;
mod explicit;
mod helpers;
mod implicit;
mod optional;
mod parser;
mod private;
pub use application::*;
pub use builder::*;
pub use explicit::*;
pub use helpers::*;
pub use implicit::*;
pub use optional::*;
pub use parser::*;
pub use private::*;
pub(crate) const CONTEXT_SPECIFIC: u8 = Class::ContextSpecific as u8;
/// A type parameter for `IMPLICIT` tagged values.
#[derive(Debug, PartialEq, Eq)]
pub enum Implicit {}
/// A type parameter for `EXPLICIT` tagged values.
#[derive(Debug, PartialEq, Eq)]
pub enum Explicit {}
/// A type parameter for tagged values either [`Explicit`] or [`Implicit`].
pub trait TagKind {}
impl TagKind for Implicit {}
impl TagKind for Explicit {}
/// Helper object for creating `FromBer`/`FromDer` types for TAGGED OPTIONAL types
///
/// When parsing `ContextSpecific` (the most common class), see [`TaggedExplicit`] and
/// [`TaggedImplicit`] alias types.
///
/// # Notes
///
/// `CLASS` must be between 0 and 4. See [`Class`] for possible values for the `CLASS` parameter.
/// Constants from this class can be used, but they must be wrapped in braces due to
/// [Rust syntax for generics](https://doc.rust-lang.org/reference/items/generics.html)
/// (see example below).
///
/// # Examples
///
/// To parse a `[APPLICATION 0] EXPLICIT INTEGER` object:
///
/// ```rust
/// use asn1_rs::{Class, Error, Explicit, FromBer, Integer, TaggedValue};
///
/// let bytes = &[0x60, 0x03, 0x2, 0x1, 0x2];
///
/// // If tagged object is present (and has expected tag), parsing succeeds:
/// let (_, tagged) =
/// TaggedValue::<Integer, Error, Explicit, {Class::APPLICATION}, 0>::from_ber(bytes)
/// .unwrap();
/// assert_eq!(tagged, TaggedValue::explicit(Integer::from(2)));
/// ```
#[derive(Debug, PartialEq, Eq)]
pub struct TaggedValue<T, E, TagKind, const CLASS: u8, const TAG: u32> {
pub(crate) inner: T,
tag_kind: PhantomData<TagKind>,
_e: PhantomData<E>,
}
impl<T, E, TagKind, const CLASS: u8, const TAG: u32> TaggedValue<T, E, TagKind, CLASS, TAG> {
/// Consumes the `TaggedParser`, returning the wrapped value.
#[inline]
pub fn into_inner(self) -> T {
self.inner
}
/// Return the (outer) tag of this object
pub const fn tag(&self) -> Tag {
Self::TAG
}
/// Return the (outer) class of this object
#[inline]
pub const fn class(&self) -> u8 {
CLASS
}
}
impl<T, E, const CLASS: u8, const TAG: u32> TaggedValue<T, E, Explicit, CLASS, TAG> {
/// Constructs a new `EXPLICIT TaggedParser` with the provided value
#[inline]
pub const fn explicit(inner: T) -> Self {
TaggedValue {
inner,
tag_kind: PhantomData,
_e: PhantomData,
}
}
}
impl<T, E, const CLASS: u8, const TAG: u32> TaggedValue<T, E, Implicit, CLASS, TAG> {
/// Constructs a new `IMPLICIT TaggedParser` with the provided value
#[inline]
pub const fn implicit(inner: T) -> Self {
TaggedValue {
inner,
tag_kind: PhantomData,
_e: PhantomData,
}
}
}
impl<T, E, TagKind, const CLASS: u8, const TAG: u32> AsRef<T>
for TaggedValue<T, E, TagKind, CLASS, TAG>
{
fn as_ref(&self) -> &T {
&self.inner
}
}
impl<T, E, TagKind, const CLASS: u8, const TAG: u32> Tagged
for TaggedValue<T, E, TagKind, CLASS, TAG>
{
const TAG: Tag = Tag(TAG);
}