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(
22        start: impl Into<Option<T>>,
23        stop: impl Into<Option<T>>,
24        step: impl Into<Option<T>>,
25    ) -> Self {
26        Self { start: start.into(), stop: stop.into(), step: step.into() }
27    }
28
29    pub fn start(&self) -> Option<T> {
30        self.start.clone()
31    }
32
33    pub fn stop(&self) -> Option<T> {
34        self.stop.clone()
35    }
36
37    pub fn step(&self) -> Option<T> {
38        self.step.clone()
39    }
40}
41
42macro_rules! impl_from_slice {
43    ($($t:ty),*) => {
44        $(
45            impl From<Slice<$t>> for Slice<isize> {
46                fn from(slice: Slice<$t>) -> Self {
47                    Self {
48                        start: slice.start.map(|v| v as isize),
49                        stop: slice.stop.map(|v| v as isize),
50                        step: slice.step.map(|v| v as isize),
51                    }
52                }
53            }
54        )*
55    };
56}
57
58impl_from_slice!(usize, u32, i32, u64, i64);
59
60impl<T> From<core::ops::Range<T>> for SliceI
61where
62    T: Integer + Clone,
63    Slice<T>: Into<SliceI>,
64{
65    fn from(range: core::ops::Range<T>) -> Self {
66        Slice::<T> { start: Some(range.start), stop: Some(range.end), step: None }.into()
67    }
68}
69
70impl<T> From<core::ops::RangeFrom<T>> for SliceI
71where
72    T: Integer + Clone,
73    Slice<T>: Into<SliceI>,
74{
75    fn from(range: core::ops::RangeFrom<T>) -> Self {
76        Slice::<T> { start: Some(range.start), stop: None, step: None }.into()
77    }
78}
79
80impl<T> From<core::ops::RangeTo<T>> for SliceI
81where
82    T: Integer + Clone,
83    Slice<T>: Into<SliceI>,
84{
85    fn from(range: core::ops::RangeTo<T>) -> Self {
86        Slice::<T> { start: None, stop: Some(range.end), step: None }.into()
87    }
88}
89
90impl From<core::ops::RangeFull> for SliceI {
91    fn from(_: core::ops::RangeFull) -> Self {
92        SliceI { start: None, stop: None, step: None }
93    }
94}