use std::{
fmt::{Debug, Display, Formatter},
str::FromStr,
};
use crate::{encoding::parse_base32, Error, Id, Type};
impl Type for () {
const PREFIX: &'static str = "";
}
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Generic {
prefix: String,
value: Id<()>,
}
impl Generic {
pub fn new(prefix: impl Into<String>, value: [u8; 16]) -> Self {
Self {
prefix: prefix.into(),
value: Id::new(value),
}
}
pub fn as_bytes(&self) -> &[u8; 16] {
&self.value.as_bytes()
}
pub fn to_bytes(self) -> [u8; 16] {
self.value.to_bytes()
}
pub fn to_u128(&self) -> u128 {
self.value.to_u128()
}
pub fn to_i128(&self) -> i128 {
self.value.to_i128()
}
pub fn test(value: &str) -> bool {
Self::parse(value).is_ok()
}
pub fn parse(value: &str) -> Result<Self, Error> {
let (prefix, value) = value.split_once('_').ok_or(Error::InvalidData)?;
Ok(Self {
prefix: prefix.to_owned(),
value: Id::new(parse_base32(value)?),
})
}
pub fn prefix(&self) -> &str {
&self.prefix
}
pub const fn cast<U: Type + ?Sized>(&self) -> Id<U> {
self.value.cast()
}
}
impl Debug for Generic {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl Display for Generic {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.prefix, self.value)
}
}
impl FromStr for Generic {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
}
}
impl From<Generic> for u128 {
fn from(value: Generic) -> Self {
value.to_u128()
}
}
impl From<Generic> for i128 {
fn from(value: Generic) -> Self {
value.to_i128()
}
}
#[cfg(test)]
mod test {
use super::Generic;
#[test]
fn generic_display() {
let id = Generic::parse("test_7zzzzzzzzzzzzzzzzzzzzzzzzz").unwrap();
assert_eq!(id.to_string(), "test_7zzzzzzzzzzzzzzzzzzzzzzzzz");
}
}