use std::fmt;
pub const DEFAULT_DEPTH_LIMIT: usize = 128;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
#[non_exhaustive]
pub enum Version {
Postbag0_4,
#[default]
Postbag1,
}
impl Version {
pub(crate) const fn is_0_4(self) -> bool {
matches!(self, Self::Postbag0_4)
}
}
impl From<Version> for u8 {
fn from(version: Version) -> Self {
match version {
Version::Postbag0_4 => 0,
Version::Postbag1 => 1,
}
}
}
impl TryFrom<u8> for Version {
type Error = UnknownVersion;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::Postbag0_4),
1 => Ok(Self::Postbag1),
unknown => Err(UnknownVersion(unknown)),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct UnknownVersion(pub u8);
impl fmt::Display for UnknownVersion {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "unknown Postbag data format version {}", self.0)
}
}
impl std::error::Error for UnknownVersion {}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Cfg<const WITH_IDENTS: bool> {
depth_limit: usize,
version: Version,
}
impl<const WITH_IDENTS: bool> Cfg<WITH_IDENTS> {
pub const DEFAULT_DEPTH_LIMIT: usize = DEFAULT_DEPTH_LIMIT;
pub const fn new() -> Self {
Self { depth_limit: DEFAULT_DEPTH_LIMIT, version: Version::Postbag1 }
}
pub const fn with_idents(&self) -> bool {
WITH_IDENTS
}
pub const fn with_depth_limit(self, depth_limit: usize) -> Self {
Self { depth_limit, ..self }
}
pub const fn with_version(self, version: Version) -> Self {
Self { version, ..self }
}
pub const fn depth_limit(&self) -> usize {
self.depth_limit
}
pub const fn version(&self) -> Version {
self.version
}
}
impl<const WITH_IDENTS: bool> Default for Cfg<WITH_IDENTS> {
fn default() -> Self {
Self::new()
}
}
impl<const WITH_IDENTS: bool> fmt::Debug for Cfg<WITH_IDENTS> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Cfg")
.field("with_idents", &WITH_IDENTS)
.field("depth_limit", &self.depth_limit)
.field("version", &self.version)
.finish()
}
}
pub type Full = Cfg<true>;
pub type Slim = Cfg<false>;