use core::fmt;
use super::Tag;
#[derive(Debug, PartialEq, Eq)]
pub enum TagCodecError {
Missing(&'static str),
Invalid(&'static str),
Unknown,
}
impl core::error::Error for TagCodecError {}
impl fmt::Display for TagCodecError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Missing(value) => write!(f, "missing {value}"),
Self::Invalid(value) => write!(f, "{value}"),
Self::Unknown => write!(f, "unknown tag"),
}
}
}
impl TagCodecError {
#[inline]
pub fn missing_tag_kind() -> Self {
Self::Missing("tag kind")
}
}
pub trait TagCodec: Sized {
type Error: core::error::Error;
fn parse<I, S>(tag: I) -> Result<Self, Self::Error>
where
I: IntoIterator<Item = S>,
S: AsRef<str>;
fn to_tag(&self) -> Tag;
}
#[macro_export]
macro_rules! impl_tag_codec_conversions {
($ty:ty) => {
impl From<&$ty> for Tag {
#[inline]
fn from(value: &$ty) -> Self {
value.to_tag()
}
}
impl From<$ty> for Tag {
#[inline]
fn from(value: $ty) -> Self {
value.to_tag()
}
}
impl TryFrom<&Tag> for $ty {
type Error = <$ty as TagCodec>::Error;
#[inline]
fn try_from(tag: &Tag) -> Result<Self, Self::Error> {
<$ty as TagCodec>::parse(tag.as_slice())
}
}
impl TryFrom<Tag> for $ty {
type Error = <$ty as TagCodec>::Error;
#[inline]
fn try_from(tag: Tag) -> Result<Self, Self::Error> {
<$ty as TagCodec>::parse(tag.as_slice())
}
}
};
}
pub use impl_tag_codec_conversions;