1extern crate alloc;
5
6use alloc::vec::Vec;
7use core::{
8 fmt,
9 ops::{Deref, DerefMut},
10 str::FromStr,
11};
12
13use crate::{Btrit, Error, Trits, T3B1};
14
15#[derive(Copy, Clone, Eq, Hash, PartialEq)]
17#[repr(i8)]
18#[allow(missing_docs)]
19pub enum Tryte {
20 N = -13,
21 O = -12,
22 P = -11,
23 Q = -10,
24 R = -9,
25 S = -8,
26 T = -7,
27 U = -6,
28 V = -5,
29 W = -4,
30 X = -3,
31 Y = -2,
32 Z = -1,
33 Nine = 0,
34 A = 1,
35 B = 2,
36 C = 3,
37 D = 4,
38 E = 5,
39 F = 6,
40 G = 7,
41 H = 8,
42 I = 9,
43 J = 10,
44 K = 11,
45 L = 12,
46 M = 13,
47}
48
49impl Tryte {
50 pub const MIN_VALUE: Self = Tryte::N;
52
53 pub const MAX_VALUE: Self = Tryte::M;
55
56 pub fn from_trits(trits: [Btrit; 3]) -> Self {
58 let x = i8::from(trits[0]) + i8::from(trits[1]) * 3 + i8::from(trits[2]) * 9;
59 Tryte::try_from(x).unwrap()
60 }
61
62 pub fn as_trits(&self) -> &Trits<T3B1> {
64 unsafe { &*(T3B1::make(self as *const _ as *const _, 0, 3) as *const _) }
65 }
66
67 pub fn as_trits_mut(&mut self) -> &mut Trits<T3B1> {
69 unsafe { &mut *(T3B1::make(self as *const _ as *const _, 0, 3) as *mut _) }
70 }
71}
72
73impl From<Tryte> for char {
74 fn from(tryte: Tryte) -> char {
75 match tryte as i8 {
76 0 => '9',
77 -13..=-1 => (((tryte as i8 + 13) as u8) + b'N') as char,
78 1..=13 => (((tryte as i8 - 1) as u8) + b'A') as char,
79 x => unreachable!("Tried to decode Tryte with variant {}", x),
80 }
81 }
82}
83
84impl From<[Btrit; 3]> for Tryte {
85 fn from(trits: [Btrit; 3]) -> Self {
86 Self::from_trits(trits)
87 }
88}
89
90impl fmt::Debug for Tryte {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 write!(f, "{:?}", char::from(*self))
93 }
94}
95
96impl fmt::Display for Tryte {
97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
98 write!(f, "{}", char::from(*self))
99 }
100}
101
102impl TryFrom<char> for Tryte {
103 type Error = Error;
104
105 fn try_from(c: char) -> Result<Self, Self::Error> {
106 match c {
107 '9' => Ok(Tryte::Nine),
108 'N'..='Z' => Ok(unsafe { core::mem::transmute((c as u8 - b'N') as i8 - 13) }),
109 'A'..='M' => Ok(unsafe { core::mem::transmute((c as u8 - b'A') as i8 + 1) }),
110 _ => Err(Error::InvalidRepr),
111 }
112 }
113}
114
115impl TryFrom<i8> for Tryte {
116 type Error = Error;
117
118 fn try_from(x: i8) -> Result<Self, Self::Error> {
119 match x {
120 -13..=13 => Ok(unsafe { core::mem::transmute(x) }),
121 _ => Err(Error::InvalidRepr),
122 }
123 }
124}
125
126#[derive(Default)]
129pub struct TryteBuf {
130 inner: Vec<Tryte>,
131}
132
133impl TryteBuf {
134 pub fn new() -> Self {
136 Self::default()
137 }
138
139 pub fn with_capacity(cap: usize) -> Self {
141 Self {
142 inner: Vec::with_capacity(cap),
143 }
144 }
145
146 pub fn try_from_str(s: &str) -> Result<Self, Error> {
148 s.chars().map(Tryte::try_from).collect()
149 }
150
151 pub fn is_empty(&self) -> bool {
153 self.len() == 0
154 }
155
156 pub fn len(&self) -> usize {
158 self.inner.len()
159 }
160
161 pub fn push(&mut self, tryte: Tryte) {
163 self.inner.push(tryte);
164 }
165
166 pub fn pop(&mut self) -> Option<Tryte> {
168 self.inner.pop()
169 }
170
171 pub fn as_trits(&self) -> &Trits<T3B1> {
173 unsafe { &*(T3B1::make(self.as_ptr() as *const _, 0, self.len() * 3) as *const _) }
174 }
175
176 pub fn as_trits_mut(&mut self) -> &mut Trits<T3B1> {
178 unsafe { &mut *(T3B1::make(self.as_ptr() as *const _, 0, self.len() * 3) as *mut _) }
179 }
180}
181
182impl Deref for TryteBuf {
183 type Target = [Tryte];
184 fn deref(&self) -> &Self::Target {
185 &self.inner
186 }
187}
188
189impl DerefMut for TryteBuf {
190 fn deref_mut(&mut self) -> &mut Self::Target {
191 &mut self.inner
192 }
193}
194
195impl FromIterator<Tryte> for TryteBuf {
196 fn from_iter<I: IntoIterator<Item = Tryte>>(iter: I) -> Self {
197 let iter = iter.into_iter();
198 let mut this = Self::with_capacity(iter.size_hint().0);
199 for tryte in iter {
200 this.push(tryte);
201 }
202 this
203 }
204}
205
206impl<'a> From<&'a [Tryte]> for TryteBuf {
207 fn from(trytes: &'a [Tryte]) -> Self {
208 Self { inner: trytes.to_vec() }
209 }
210}
211
212impl FromStr for TryteBuf {
213 type Err = Error;
214
215 fn from_str(s: &str) -> Result<Self, Self::Err> {
216 Self::try_from_str(s)
217 }
218}
219
220impl fmt::Debug for TryteBuf {
221 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222 write!(f, "{:?}", self.inner)
223 }
224}
225
226impl fmt::Display for TryteBuf {
227 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
228 for tryte in self.iter() {
229 write!(f, "{}", tryte)?;
230 }
231 Ok(())
232 }
233}