polars_utils/
idx_mapper.rs

1use std::ops::Range;
2
3/// Reverses indexing direction
4pub struct IdxMapper {
5    total_len: usize,
6    reverse: bool,
7}
8
9impl IdxMapper {
10    pub fn new(total_len: usize, reverse: bool) -> Self {
11        Self { total_len, reverse }
12    }
13}
14
15impl IdxMapper {
16    /// # Panics
17    /// `range.end <= self.total_len`
18    #[inline]
19    pub fn map_range(&self, range: Range<usize>) -> Range<usize> {
20        if self.reverse {
21            // len: 5
22            // array: [0 1 2 3 4]
23            // slice: [    2 3  ]
24            // in:  1..3 (right-to-left)
25            // out: 2..4
26            map_range::<true>(self.total_len, range)
27        } else {
28            range
29        }
30    }
31}
32
33/// # Safety
34/// `range.end <= total_len`
35#[inline]
36pub fn map_range<const REVERSE: bool>(total_len: usize, range: Range<usize>) -> Range<usize> {
37    assert!(range.end <= total_len);
38    if REVERSE {
39        total_len - range.end..total_len - range.start
40    } else {
41        range
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::IdxMapper;
48
49    #[test]
50    fn test_idx_map_roundtrip() {
51        let map = IdxMapper::new(100, true);
52
53        assert_eq!(map.map_range(map.map_range(5..77)), 5..77);
54    }
55}