1
2use crate::{
3 BytesRead, ReadError, BytesWrite, WriteError, BytesSeek, SeekError, Bytes
4};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub struct Offset<T> {
24 offset: usize,
27 inner: T
28}
29
30impl<T> Offset<T> {
31
32 pub fn new(mut inner: T, offset: usize) -> Self
37 where T: BytesRead + BytesSeek {
38 inner.seek(inner.position() + offset);
39 Self { inner, offset }
40 }
41
42 pub fn set_offset(&mut self, offset: usize)
46 where T: BytesSeek {
47 let prev_pos = self.inner.position() - self.offset;
48 self.inner.seek(prev_pos + offset);
49 self.offset = offset;
50 }
51
52 pub fn offset(&self) -> usize {
54 self.offset
55 }
56
57 pub fn inner(&self) -> &T {
59 &self.inner
60 }
61
62 pub fn inner_mut(&mut self) -> &mut T {
66 &mut self.inner
67 }
68
69 pub fn into_inner(self) -> T {
71 self.inner
72 }
73
74}
75
76impl<T> BytesRead for Offset<T>
77where T: BytesRead {
78 #[inline]
79 fn as_slice(&self) -> &[u8] {
80 &self.inner.as_slice()[self.offset..]
81 }
82
83 #[inline]
84 fn remaining(&self) -> &[u8] {
85 self.inner.remaining()
86 }
87
88 fn try_read(&mut self, len: usize) -> Result<&[u8], ReadError> {
89 self.inner.try_read(len)
90 }
91
92 fn peek(&self, len: usize) -> Option<&[u8]> {
93 self.inner.peek(len)
94 }
95}
96
97impl<T> BytesSeek for Offset<T>
98where T: BytesSeek {
99 fn position(&self) -> usize {
101 self.inner.position() - self.offset
102 }
103
104 fn try_seek(&mut self, pos: usize) -> Result<(), SeekError> {
109 self.inner.try_seek(self.offset + pos)
110 }
111}
112
113impl<T> BytesWrite for Offset<T>
114where T: BytesWrite {
115 fn as_mut(&mut self) -> &mut [u8] {
116 &mut self.inner.as_mut()[self.offset..]
117 }
118
119 fn as_bytes(&self) -> Bytes<'_> {
120 self.inner.as_bytes().inner()[self.offset..].into()
121 }
122
123 fn remaining_mut(&mut self) -> &mut [u8] {
124 self.inner.remaining_mut()
125 }
126
127 fn try_write(&mut self, slice: impl AsRef<[u8]>) -> Result<(), WriteError> {
128 self.inner.try_write(slice)
129 }
130}
131
132
133
134#[cfg(test)]
135mod tests {
136
137 use super::*;
138 use crate::Cursor;
139
140 #[test]
141 fn write() {
142
143 let cursor = Cursor::new(vec![1, 2, 3, 4]);
144 let mut offset_cursor = Offset::new(cursor, 2);
145 assert_eq!(offset_cursor.remaining_mut().len(), 2);
146 offset_cursor.write(&[1]);
147 assert_eq!(offset_cursor.remaining_mut().len(), 1);
148 offset_cursor.write(&[2]);
149 assert_eq!(offset_cursor.remaining_mut().len(), 0);
150 offset_cursor.write(&[1, 2]);
151
152 assert_eq!(offset_cursor.as_mut(), &[1, 2, 1, 2]);
153
154 }
155
156 #[test]
157 fn read() {
158
159 let cursor = Cursor::new(vec![1, 2, 3, 4]);
160 let mut offset_cursor = Offset::new(cursor, 2);
161 assert_eq!(offset_cursor.position(), 0);
162 offset_cursor.seek(1);
163 assert_eq!(offset_cursor.position(), 1);
164 assert_eq!(offset_cursor.as_slice(), &[3, 4]);
165 assert_eq!(offset_cursor.remaining(), &[4]);
166
167 offset_cursor.set_offset(1);
168 assert_eq!(offset_cursor.position(), 1);
169 assert_eq!(offset_cursor.as_slice(), &[2, 3, 4]);
170 assert_eq!(offset_cursor.remaining(), &[3, 4]);
171
172 }
173
174}