use crate::Error;
use core::num::NonZeroU8;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum DeriveDomain {
User,
Document,
Session,
Device,
Concept,
Custom(NonZeroU8),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Domain {
User,
Document,
Session,
Device,
Concept,
Custom(u8),
Opaque,
}
impl Domain {
pub const OPAQUE_BYTE: u8 = 0x00;
#[must_use]
pub const fn builtins() -> &'static [Self] {
&[
Self::User,
Self::Document,
Self::Session,
Self::Device,
Self::Concept,
]
}
}
impl DeriveDomain {
pub const fn custom(byte: u8) -> Result<Self, Error> {
match NonZeroU8::new(byte) {
Some(byte) => Ok(Self::Custom(byte)),
None => Err(Error::ReservedDomain),
}
}
#[inline]
pub(crate) const fn as_byte(self) -> u8 {
match self {
Self::User => 0x01,
Self::Document => 0x02,
Self::Session => 0x03,
Self::Device => 0x04,
Self::Concept => 0x05,
Self::Custom(b) => b.get(),
}
}
#[must_use]
pub const fn builtins() -> &'static [Self] {
&[
Self::User,
Self::Document,
Self::Session,
Self::Device,
Self::Concept,
]
}
}
impl From<DeriveDomain> for Domain {
fn from(domain: DeriveDomain) -> Self {
match domain {
DeriveDomain::User => Self::User,
DeriveDomain::Document => Self::Document,
DeriveDomain::Session => Self::Session,
DeriveDomain::Device => Self::Device,
DeriveDomain::Concept => Self::Concept,
DeriveDomain::Custom(b) => Self::Custom(b.get()),
}
}
}
impl TryFrom<Domain> for DeriveDomain {
type Error = Error;
fn try_from(domain: Domain) -> Result<Self, Self::Error> {
match domain {
Domain::User => Ok(Self::User),
Domain::Document => Ok(Self::Document),
Domain::Session => Ok(Self::Session),
Domain::Device => Ok(Self::Device),
Domain::Concept => Ok(Self::Concept),
Domain::Custom(b) => Self::custom(b),
Domain::Opaque => Err(Error::ReservedDomain),
}
}
}
impl core::fmt::Display for Domain {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::User => write!(f, "user"),
Self::Document => write!(f, "document"),
Self::Session => write!(f, "session"),
Self::Device => write!(f, "device"),
Self::Concept => write!(f, "concept"),
Self::Custom(b) => write!(f, "custom:{b:02x}"),
Self::Opaque => write!(f, "opaque"),
}
}
}
impl core::fmt::Display for DeriveDomain {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
Domain::from(*self).fmt(f)
}
}