#[derive(Debug, Clone, PartialEq)]
pub enum SliceSpec {
Range {
start: Option<isize>,
stop: Option<isize>,
step: Option<isize>,
},
Index(isize),
Ellipsis,
NewAxis,
}
impl SliceSpec {
pub fn range(start: Option<isize>, stop: Option<isize>, step: Option<isize>) -> Self {
SliceSpec::Range { start, stop, step }
}
pub fn from_to(start: isize, stop: isize) -> Self {
SliceSpec::Range {
start: Some(start),
stop: Some(stop),
step: Some(1),
}
}
pub fn from(start: isize) -> Self {
SliceSpec::Range {
start: Some(start),
stop: None,
step: Some(1),
}
}
pub fn to(stop: isize) -> Self {
SliceSpec::Range {
start: None,
stop: Some(stop),
step: Some(1),
}
}
pub fn step(step: isize) -> Self {
SliceSpec::Range {
start: None,
stop: None,
step: Some(step),
}
}
pub fn full() -> Self {
SliceSpec::Range {
start: None,
stop: None,
step: Some(1),
}
}
}
pub fn s_(specs: &[SliceSpec]) -> Vec<SliceSpec> {
specs.to_vec()
}
pub const NEWAXIS: SliceSpec = SliceSpec::NewAxis;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_slice_spec() {
let slice = SliceSpec::range(Some(1), Some(5), Some(2));
match slice {
SliceSpec::Range { start, stop, step } => {
assert_eq!(start, Some(1));
assert_eq!(stop, Some(5));
assert_eq!(step, Some(2));
}
_ => panic!("Expected Range slice"),
}
let from_to = SliceSpec::from_to(1, 5);
let from = SliceSpec::from(2);
let to = SliceSpec::to(5);
let step = SliceSpec::step(2);
let full = SliceSpec::full();
assert!(matches!(from_to, SliceSpec::Range { .. }));
assert!(matches!(from, SliceSpec::Range { .. }));
assert!(matches!(to, SliceSpec::Range { .. }));
assert!(matches!(step, SliceSpec::Range { .. }));
assert!(matches!(full, SliceSpec::Range { .. }));
let index = SliceSpec::Index(3);
assert!(matches!(index, SliceSpec::Index(3)));
let ellipsis = SliceSpec::Ellipsis;
assert!(matches!(ellipsis, SliceSpec::Ellipsis));
let newaxis = SliceSpec::NewAxis;
assert!(matches!(newaxis, SliceSpec::NewAxis));
assert_eq!(newaxis, NEWAXIS);
}
#[test]
fn test_s_() {
let slices = s_(&[
SliceSpec::from_to(1, 5),
SliceSpec::step(2),
SliceSpec::Index(3),
]);
assert_eq!(slices.len(), 3);
assert!(matches!(slices[0], SliceSpec::Range { .. }));
assert!(matches!(slices[1], SliceSpec::Range { .. }));
assert!(matches!(slices[2], SliceSpec::Index(3)));
let empty_slices = s_(&[]);
assert_eq!(empty_slices.len(), 0);
}
}