vildrose_core/word/
basic.rs1use super::Word;
2use crate::trit::Trit;
3use core::cmp::Ordering;
4use core::fmt;
5use core::ops::Neg;
6
7impl<const N: usize> Word<N> {
10 pub const TRIT_COUNT: usize = N;
12
13 #[must_use]
17 pub const fn new(trits: [Trit; N]) -> Self {
18 Self(trits)
19 }
20
21 #[must_use]
23 pub const fn zero() -> Self {
24 Self([Trit::Z; N])
25 }
26
27 #[must_use]
29 pub const fn into_trits(self) -> [Trit; N] {
30 self.0
31 }
32
33 #[must_use]
37 pub fn get_trit(self, index: usize) -> Option<Trit> {
38 self.0.get(index).copied()
39 }
40
41 #[must_use]
47 pub const fn trit(self, index: usize) -> Trit {
48 self.0[index]
49 }
50
51 #[must_use]
53 pub fn negate(self) -> Self {
54 Self(self.0.map(Trit::negate))
55 }
56
57 #[must_use]
59 pub fn sign(self) -> Trit {
60 self.0
61 .iter()
62 .rev()
63 .copied()
64 .find(|&trit| trit != Trit::Z)
65 .unwrap_or(Trit::Z)
66 }
67
68 #[must_use]
70 pub fn abs(self) -> Self {
71 if self.sign() == Trit::N { -self } else { self }
72 }
73
74 #[must_use]
81 pub fn truncate<const W: usize>(self) -> Word<W> {
82 assert!(W <= N, "cannot truncate Word<{N}> into wider Word<{W}>");
83
84 Word(core::array::from_fn(|index| self.0[index]))
85 }
86}
87
88impl<const N: usize> Neg for Word<N> {
89 type Output = Self;
90
91 fn neg(self) -> Self::Output {
92 self.negate()
93 }
94}
95
96impl<const N: usize> PartialOrd for Word<N> {
97 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
98 Some(self.cmp(other))
99 }
100}
101
102impl<const N: usize> Ord for Word<N> {
103 fn cmp(&self, other: &Self) -> Ordering {
104 self.0
105 .iter()
106 .rev()
107 .zip(other.0.iter().rev())
108 .map(|(left, right)| left.cmp(right))
109 .find(|&ordering| ordering != Ordering::Equal)
110 .unwrap_or(Ordering::Equal)
111 }
112}
113
114impl<const N: usize> fmt::Display for Word<N> {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 for trit in self.0.iter().rev() {
117 write!(f, "{trit}")?;
118 }
119
120 Ok(())
121 }
122}