#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Column(usize);
impl Column {
#[must_use]
pub fn new(index: usize) -> Self {
Self(index)
}
#[must_use]
pub fn index(self) -> usize {
self.0
}
}
impl core::fmt::Display for Column {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "c{}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ColumnCount(usize);
impl ColumnCount {
#[must_use]
pub fn new(n: usize) -> Self {
Self(n)
}
#[must_use]
pub fn count(self) -> usize {
self.0
}
#[must_use]
pub fn zero() -> Self {
Self(0)
}
#[must_use]
pub fn tensor(self, other: Self) -> Self {
Self(self.0 + other.0)
}
}
impl std::ops::Add for ColumnCount {
type Output = Self;
fn add(self, rhs: Self) -> Self {
self.tensor(rhs)
}
}
impl core::fmt::Display for ColumnCount {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ColumnRef {
Current(Column),
Next(Column),
}
impl ColumnRef {
#[must_use]
pub fn column(self) -> Column {
match self {
Self::Current(c) | Self::Next(c) => c,
}
}
#[must_use]
pub fn is_current(self) -> bool {
matches!(self, Self::Current(_))
}
#[must_use]
pub fn is_next(self) -> bool {
matches!(self, Self::Next(_))
}
}
impl core::fmt::Display for ColumnRef {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Current(c) => write!(f, "curr.{c}"),
Self::Next(c) => write!(f, "next.{c}"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn column_count_tensor_is_addition() {
let a = ColumnCount::new(3);
let b = ColumnCount::new(4);
assert_eq!(a.tensor(b), ColumnCount::new(7));
assert_eq!(a + b, ColumnCount::new(7));
}
#[test]
fn column_ref_accessors() {
let curr = ColumnRef::Current(Column::new(2));
assert!(curr.is_current());
assert!(!curr.is_next());
assert_eq!(curr.column(), Column::new(2));
let next = ColumnRef::Next(Column::new(5));
assert!(next.is_next());
assert!(!next.is_current());
assert_eq!(next.column(), Column::new(5));
}
#[test]
fn column_display() {
assert_eq!(format!("{}", Column::new(3)), "c3");
}
#[test]
fn column_ref_display() {
assert_eq!(format!("{}", ColumnRef::Current(Column::new(0))), "curr.c0");
assert_eq!(format!("{}", ColumnRef::Next(Column::new(1))), "next.c1");
}
}