1use crate::identifier::Identifier;
4use crate::state::State;
5
6#[derive(Clone, Copy)]
29pub struct EncodedPin {
30 buf: [u8; 3],
31 len: u8,
32}
33
34impl EncodedPin {
35 #[must_use]
37 pub(crate) fn from_identifier(id: Identifier) -> Self {
38 let mut buf = [0u8; 3];
39 let mut len: u8 = 0;
40
41 if let Some(modifier) = state_modifier(id.state()) {
43 buf[usize::from(len)] = modifier;
44 len += 1;
45 }
46
47 buf[usize::from(len)] = id.letter().to_ascii(id.side());
49 len += 1;
50
51 if id.is_terminal() {
53 buf[usize::from(len)] = b'^';
54 len += 1;
55 }
56
57 Self { buf, len }
58 }
59
60 #[must_use]
62 pub fn as_str(&self) -> &str {
63 let bytes = &self.buf[..usize::from(self.len)];
64 debug_assert!(bytes.is_ascii(), "EncodedPin must contain only ASCII bytes");
65 core::str::from_utf8(bytes).unwrap_or("")
68 }
69}
70
71impl core::ops::Deref for EncodedPin {
72 type Target = str;
73
74 fn deref(&self) -> &str {
75 self.as_str()
76 }
77}
78
79impl AsRef<str> for EncodedPin {
80 fn as_ref(&self) -> &str {
81 self.as_str()
82 }
83}
84
85impl core::fmt::Display for EncodedPin {
86 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
87 f.write_str(self.as_str())
88 }
89}
90
91impl core::fmt::Debug for EncodedPin {
92 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93 write!(f, "EncodedPin({:?})", self.as_str())
94 }
95}
96
97impl PartialEq<str> for EncodedPin {
98 fn eq(&self, other: &str) -> bool {
99 self.as_str() == other
100 }
101}
102
103impl PartialEq<&str> for EncodedPin {
104 fn eq(&self, other: &&str) -> bool {
105 self.as_str() == *other
106 }
107}
108
109impl PartialEq<EncodedPin> for str {
110 fn eq(&self, other: &EncodedPin) -> bool {
111 self == other.as_str()
112 }
113}
114
115impl PartialEq<EncodedPin> for &str {
116 fn eq(&self, other: &EncodedPin) -> bool {
117 *self == other.as_str()
118 }
119}
120
121const fn state_modifier(state: State) -> Option<u8> {
124 match state {
125 State::Normal => None,
126 State::Enhanced => Some(b'+'),
127 State::Diminished => Some(b'-'),
128 }
129}