rstsr_common/layout/
slice.rs

1use num::Integer;
2
3/// Slicing for python (numpy) convention; somehow similar to Rust's range.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct Slice<T>
6where
7    T: Integer + Clone,
8{
9    pub(crate) start: Option<T>,
10    pub(crate) stop: Option<T>,
11    pub(crate) step: Option<T>,
12}
13
14/// In most cases, we will use isize for indexing.
15pub type SliceI = Slice<isize>;
16
17impl<T> Slice<T>
18where
19    T: Integer + Clone,
20{
21    pub fn new(start: impl Into<Option<T>>, stop: impl Into<Option<T>>, step: impl Into<Option<T>>) -> Self {
22        Self { start: start.into(), stop: stop.into(), step: step.into() }
23    }
24
25    pub fn start(&self) -> Option<T> {
26        self.start.clone()
27    }
28
29    pub fn stop(&self) -> Option<T> {
30        self.stop.clone()
31    }
32
33    pub fn step(&self) -> Option<T> {
34        self.step.clone()
35    }
36}
37
38macro_rules! impl_from_slice {
39    ($($t:ty),*) => {
40        $(
41            impl From<Slice<$t>> for Slice<isize> {
42                fn from(slice: Slice<$t>) -> Self {
43                    Self {
44                        start: slice.start.map(|v| v as isize),
45                        stop: slice.stop.map(|v| v as isize),
46                        step: slice.step.map(|v| v as isize),
47                    }
48                }
49            }
50        )*
51    };
52}
53
54impl_from_slice!(usize, u32, i32, u64, i64);
55
56impl<T> From<core::ops::Range<T>> for SliceI
57where
58    T: Integer + Clone,
59    Slice<T>: Into<SliceI>,
60{
61    fn from(range: core::ops::Range<T>) -> Self {
62        Slice::<T> { start: Some(range.start), stop: Some(range.end), step: None }.into()
63    }
64}
65
66impl<T> From<core::ops::RangeFrom<T>> for SliceI
67where
68    T: Integer + Clone,
69    Slice<T>: Into<SliceI>,
70{
71    fn from(range: core::ops::RangeFrom<T>) -> Self {
72        Slice::<T> { start: Some(range.start), stop: None, step: None }.into()
73    }
74}
75
76impl<T> From<core::ops::RangeTo<T>> for SliceI
77where
78    T: Integer + Clone,
79    Slice<T>: Into<SliceI>,
80{
81    fn from(range: core::ops::RangeTo<T>) -> Self {
82        Slice::<T> { start: None, stop: Some(range.end), step: None }.into()
83    }
84}
85
86impl From<core::ops::RangeFull> for SliceI {
87    fn from(_: core::ops::RangeFull) -> Self {
88        SliceI { start: None, stop: None, step: None }
89    }
90}