use std::ops::Range;
use crate::matrices::{Column, Row};
#[non_exhaustive]
pub enum Slice {
All(),
None(),
Single(usize),
Range(Range<usize>),
Not(Box<Slice>),
And(Box<Slice>, Box<Slice>),
Or(Box<Slice>, Box<Slice>),
}
pub struct Slice2D {
pub(crate) rows: Slice,
pub(crate) columns: Slice,
}
impl Slice {
pub fn accepts(&self, index: usize) -> bool {
match self {
Slice::All() => true,
Slice::None() => false,
Slice::Single(i) => i == &index,
Slice::Range(range) => range.contains(&index),
Slice::Not(slice) => !slice.accepts(index),
Slice::And(slice1, slice2) => slice1.accepts(index) && slice2.accepts(index),
Slice::Or(slice1, slice2) => slice1.accepts(index) || slice2.accepts(index),
}
}
#[allow(clippy::should_implement_trait)]
pub fn not(self) -> Slice {
Slice::Not(Box::new(self))
}
pub fn and(self, other: Slice) -> Slice {
Slice::And(Box::new(self), Box::new(other))
}
pub fn or(self, other: Slice) -> Slice {
Slice::Or(Box::new(self), Box::new(other))
}
}
pub struct EmptySlice2DBuilder {}
pub struct RowSlice2DBuilder {
rows: Slice,
}
pub struct ColumnSlice2DBuilder {
columns: Slice,
}
pub fn new() -> EmptySlice2DBuilder {
Slice2D::new()
}
impl Slice2D {
#[allow(clippy::new_ret_no_self)]
pub fn new() -> EmptySlice2DBuilder {
EmptySlice2DBuilder {}
}
pub fn accepts(&self, row: Row, column: Column) -> bool {
self.rows.accepts(row) && self.columns.accepts(column)
}
}
impl EmptySlice2DBuilder {
pub fn rows(self, rows: Slice) -> RowSlice2DBuilder {
RowSlice2DBuilder { rows }
}
pub fn columns(self, columns: Slice) -> ColumnSlice2DBuilder {
ColumnSlice2DBuilder { columns }
}
}
impl RowSlice2DBuilder {
pub fn columns(self, columns: Slice) -> Slice2D {
Slice2D {
rows: self.rows,
columns,
}
}
}
impl ColumnSlice2DBuilder {
pub fn rows(self, rows: Slice) -> Slice2D {
Slice2D {
rows,
columns: self.columns,
}
}
}