1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub struct Column(usize);
22
23impl Column {
24 #[must_use]
26 pub fn new(index: usize) -> Self {
27 Self(index)
28 }
29
30 #[must_use]
32 pub fn index(self) -> usize {
33 self.0
34 }
35}
36
37impl core::fmt::Display for Column {
38 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
39 write!(f, "c{}", self.0)
40 }
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
58pub struct ColumnCount(usize);
59
60impl ColumnCount {
61 #[must_use]
63 pub fn new(n: usize) -> Self {
64 Self(n)
65 }
66
67 #[must_use]
69 pub fn count(self) -> usize {
70 self.0
71 }
72
73 #[must_use]
75 pub fn zero() -> Self {
76 Self(0)
77 }
78
79 #[must_use]
81 pub fn tensor(self, other: Self) -> Self {
82 Self(self.0 + other.0)
83 }
84}
85
86impl std::ops::Add for ColumnCount {
87 type Output = Self;
88 fn add(self, rhs: Self) -> Self {
89 self.tensor(rhs)
90 }
91}
92
93impl core::fmt::Display for ColumnCount {
94 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95 write!(f, "{}", self.0)
96 }
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub enum ColumnRef {
118 Current(Column),
120 Next(Column),
122}
123
124impl ColumnRef {
125 #[must_use]
127 pub fn column(self) -> Column {
128 match self {
129 Self::Current(c) | Self::Next(c) => c,
130 }
131 }
132
133 #[must_use]
135 pub fn is_current(self) -> bool {
136 matches!(self, Self::Current(_))
137 }
138
139 #[must_use]
141 pub fn is_next(self) -> bool {
142 matches!(self, Self::Next(_))
143 }
144}
145
146impl core::fmt::Display for ColumnRef {
147 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
148 match self {
149 Self::Current(c) => write!(f, "curr.{c}"),
150 Self::Next(c) => write!(f, "next.{c}"),
151 }
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 fn column_count_tensor_is_addition() {
161 let a = ColumnCount::new(3);
162 let b = ColumnCount::new(4);
163 assert_eq!(a.tensor(b), ColumnCount::new(7));
164 assert_eq!(a + b, ColumnCount::new(7));
165 }
166
167 #[test]
168 fn column_ref_accessors() {
169 let curr = ColumnRef::Current(Column::new(2));
170 assert!(curr.is_current());
171 assert!(!curr.is_next());
172 assert_eq!(curr.column(), Column::new(2));
173
174 let next = ColumnRef::Next(Column::new(5));
175 assert!(next.is_next());
176 assert!(!next.is_current());
177 assert_eq!(next.column(), Column::new(5));
178 }
179
180 #[test]
181 fn column_display() {
182 assert_eq!(format!("{}", Column::new(3)), "c3");
183 }
184
185 #[test]
186 fn column_ref_display() {
187 assert_eq!(format!("{}", ColumnRef::Current(Column::new(0))), "curr.c0");
188 assert_eq!(format!("{}", ColumnRef::Next(Column::new(1))), "next.c1");
189 }
190}