yui_core/ext/
range.rs

1use std::ops::{Add, Neg, Range, RangeInclusive, Sub};
2
3pub trait RangeExt {
4    type Idx; 
5    fn mv(&self, l: Self::Idx, r: Self::Idx) -> Self;
6    fn shift(&self, a: Self::Idx) -> Self;
7    fn expand(&self, a: Self::Idx) -> Self;
8}
9
10impl<Idx> RangeExt for Range<Idx>
11where Idx: Copy + Add<Output = Idx> + Sub<Output = Idx> + Neg<Output = Idx> {
12    type Idx = Idx;
13
14    fn mv(&self, l: Self::Idx, r: Self::Idx) -> Self {
15        (self.start + l) .. (self.end + r)
16    }
17
18    fn shift(&self, a: Idx) -> Self {
19        self.mv(a, a)
20    }
21    
22    fn expand(&self, a: Self::Idx) -> Self {
23        self.mv(-a, a)
24    }    
25}
26
27impl<Idx> RangeExt for RangeInclusive<Idx>
28where Idx: Copy + Add<Output = Idx> + Sub<Output = Idx> + Neg<Output = Idx> {
29    type Idx = Idx;
30    
31    fn mv(&self, l: Self::Idx, r: Self::Idx) -> Self {
32        (*self.start() + l) ..= (*self.end() + r)
33    }
34
35    fn shift(&self, a: Idx) -> Self {
36        self.mv(a, a)
37    }
38    
39    fn expand(&self, a: Self::Idx) -> Self {
40        self.mv(-a, a)
41    }    
42}
43
44#[cfg(test)]
45mod tests {
46    use crate::RangeExt;
47 
48    #[test]
49    fn range() { 
50        let r = -1 .. 3;
51        assert_eq!(r.mv(2, 3), 1 .. 6);
52        assert_eq!(r.shift(2), 1 .. 5);
53        assert_eq!(r.expand(2), -3 .. 5);
54    }
55
56    #[test]
57    fn range_incl() { 
58        let r = -1 ..= 3;
59        assert_eq!(r.mv(2, 3), 1 ..= 6);
60        assert_eq!(r.shift(2), 1 ..= 5);
61        assert_eq!(r.expand(2), -3 ..= 5);
62    }
63}