1pub mod with_offset;
2pub use with_offset::WithOffset;
3
4use std::ops::{Index, IndexMut};
5use std::slice::SliceIndex;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct OffsetSlice<'a, T> {
9 parent: &'a [T],
10 offset: isize,
11}
12
13impl<'a, T> OffsetSlice<'a, T> {
14 pub fn new(parent: &'a [T], offset: isize) -> OffsetSlice<'a, T> {
15 OffsetSlice { parent, offset }
16 }
17}
18
19impl<'a, T, I> Index<I> for OffsetSlice<'a, T>
30where
31 I: WithOffset<isize>,
32 I::Output: SliceIndex<[T]>,
33{
34 type Output = <I::Output as SliceIndex<[T]>>::Output;
35 fn index(&self, index: I) -> &Self::Output {
36 let index = index.with_offset(self.offset);
37 self.parent.index(index)
38 }
39}
40
41#[derive(Debug, PartialEq, Eq)]
42pub struct OffsetSliceMut<'a, T> {
43 parent: &'a mut [T],
44 offset: isize,
45}
46
47impl<'a, T> OffsetSliceMut<'a, T> {
48 pub fn new(parent: &'a mut [T], offset: isize) -> OffsetSliceMut<'a, T> {
49 OffsetSliceMut { parent, offset }
50 }
51}
52
53impl<'a, T, I> Index<I> for OffsetSliceMut<'a, T>
54where
55 I: WithOffset<isize>,
56 I::Output: SliceIndex<[T]>,
57{
58 type Output = <I::Output as SliceIndex<[T]>>::Output;
59 fn index(&self, index: I) -> &Self::Output {
60 let index = index.with_offset(self.offset);
61 self.parent.index(index)
62 }
63}
64
65impl<'a, T, I> IndexMut<I> for OffsetSliceMut<'a, T>
66where
67 I: WithOffset<isize>,
68 I::Output: SliceIndex<[T]>,
69{
70 fn index_mut(&mut self, index: I) -> &mut Self::Output {
71 let index = index.with_offset(self.offset);
72 self.parent.index_mut(index)
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77struct OffsetView<P, O> {
78 parent: P,
79 offset: O,
80}
81
82impl<P, O> OffsetView<P, O> {
83 fn new(parent: P, offset: O) -> OffsetView<P, O> {
84 OffsetView { parent, offset }
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use cool_asserts::assert_panics;
92
93 #[test]
94 fn offset_slice_works() {
95 let a = [0, 1, 2, 3, 4, 5];
96 let os = OffsetSlice::new(&a, -3isize);
97 for i in 3..=8 {
98 assert_eq!(os[i], i - 3);
99 }
100 assert_panics!(os[2], includes("cannot convert to `usize`"));
101 assert_panics!(os[9], includes("index out of bounds"));
102 }
103
104 #[test]
105 fn offset_slice_mut_works() {
106 let mut a = [0, 1, 2, 3, 4, 5];
107 let mut os = OffsetSliceMut::new(&mut a, -3isize);
108 for i in 3..=8 {
109 assert_eq!(os[i], i - 3);
110 os[i] = 0;
111 }
112 assert_panics!(os[2], includes("cannot convert to `usize`"));
113 assert_panics!(os[9], includes("index out of bounds"));
114 for i in 3..=8 {
115 assert_eq!(os[i], 0);
116 }
117 }
118
119 #[test]
120 fn can_create_from_string() {
121 let parent = String::from("Hello!");
122 let view = OffsetView::new(&parent, -2);
123 assert_eq!(view.parent, &parent);
124 assert_eq!(view.offset, -2);
125 }
126
127 #[test]
128 fn can_create_from_array() {
129 let parent = [0, 1, 2, 3];
130 let view = OffsetView::new(&parent, -2);
131 assert_eq!(view.parent, &parent);
132 assert_eq!(view.offset, -2);
133 }
134}