use crate::identifier::Identifier;
use crate::state::State;
#[derive(Clone, Copy)]
pub struct EncodedPin {
buf: [u8; 3],
len: u8,
}
impl EncodedPin {
#[must_use]
pub(crate) fn from_identifier(id: Identifier) -> Self {
let mut buf = [0u8; 3];
let mut len: u8 = 0;
if let Some(modifier) = state_modifier(id.state()) {
buf[usize::from(len)] = modifier;
len += 1;
}
buf[usize::from(len)] = id.letter().to_ascii(id.side());
len += 1;
if id.is_terminal() {
buf[usize::from(len)] = b'^';
len += 1;
}
Self { buf, len }
}
#[must_use]
pub fn as_str(&self) -> &str {
let bytes = &self.buf[..usize::from(self.len)];
debug_assert!(bytes.is_ascii(), "EncodedPin must contain only ASCII bytes");
core::str::from_utf8(bytes).unwrap_or("")
}
}
impl core::ops::Deref for EncodedPin {
type Target = str;
fn deref(&self) -> &str {
self.as_str()
}
}
impl AsRef<str> for EncodedPin {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl core::fmt::Display for EncodedPin {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
impl core::fmt::Debug for EncodedPin {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "EncodedPin({:?})", self.as_str())
}
}
impl PartialEq<str> for EncodedPin {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl PartialEq<&str> for EncodedPin {
fn eq(&self, other: &&str) -> bool {
self.as_str() == *other
}
}
impl PartialEq<EncodedPin> for str {
fn eq(&self, other: &EncodedPin) -> bool {
self == other.as_str()
}
}
impl PartialEq<EncodedPin> for &str {
fn eq(&self, other: &EncodedPin) -> bool {
*self == other.as_str()
}
}
const fn state_modifier(state: State) -> Option<u8> {
match state {
State::Normal => None,
State::Enhanced => Some(b'+'),
State::Diminished => Some(b'-'),
}
}