use std::any::type_name;
use std::fmt::{Debug, Display, Formatter};
use std::ops::Deref;
pub const NAME_MAX_LEN: usize = 7;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Name {
buf: [u8; NAME_MAX_LEN],
len: u8,
}
impl Name {
pub(crate) fn new(input: impl AsRef<str>) -> Self {
let mut buf = [0u8; NAME_MAX_LEN];
let mut len = 0usize;
for mut b in input
.as_ref()
.bytes()
.filter(u8::is_ascii_alphanumeric)
.take(NAME_MAX_LEN)
{
b.make_ascii_lowercase(); buf[len] = b;
len += 1;
}
Name {
buf,
len: len as u8,
}
}
pub fn as_str(&self) -> &str {
std::str::from_utf8(&self.buf[..self.len as usize]).expect(concat!(
"it should be possible to view the internal buffer as a &str because",
" the constructor of this struct always interprets the input string",
" as a sequence of valid UTF-8 characters",
))
}
}
impl Debug for Name {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct(type_name::<Self>())
.field("buf", &self.as_str())
.finish()
}
}
impl Display for Name {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl AsRef<str> for Name {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Deref for Name {
type Target = str;
fn deref(&self) -> &Self::Target {
self.as_str()
}
}