positioned_io_preview/
cursor.rs1use std::io;
2use std::io::{Read, Seek, SeekFrom, Write};
3
4use super::{ReadAt, Size, WriteAt};
5
6#[derive(Debug, Clone)]
54pub struct Cursor<I> {
55 io: I,
56 pos: u64,
57}
58
59impl<I> Cursor<I> {
60 #[inline]
64 pub fn new_pos(io: I, pos: u64) -> Self {
65 Cursor { io, pos }
66 }
67
68 #[inline]
72 pub fn new(io: I) -> Self {
73 Self::new_pos(io, 0)
74 }
75
76 #[inline]
78 pub fn into_inner(self) -> I {
79 self.io
80 }
81
82 #[inline]
84 pub fn get_ref(&self) -> &I {
85 &self.io
86 }
87
88 #[inline]
90 pub fn get_mut(&mut self) -> &mut I {
91 &mut self.io
92 }
93
94 #[inline]
96 pub fn position(&self) -> u64 {
97 self.pos
98 }
99
100 #[inline]
102 pub fn set_position(&mut self, pos: u64) {
103 self.pos = pos;
104 }
105}
106
107impl<I> Seek for Cursor<I> {
108 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
109 match pos {
110 SeekFrom::Start(p) => self.pos = p,
111 SeekFrom::Current(p) => {
112 let pos = self.pos as i64 + p;
113 if pos < 0 {
114 return Err(io::Error::new(io::ErrorKind::InvalidInput, "seek to a negative position"));
115 }
116 self.pos = pos as u64;
117 }
118 SeekFrom::End(_) => {
119 return Err(io::Error::new(io::ErrorKind::InvalidInput, "seek from unknown end"))
120 }
121 }
122 Ok(self.pos)
123 }
124}
125
126impl<I: ReadAt> Read for Cursor<I> {
127 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
128 let bytes = self.get_ref().read_at(self.pos, buf)?;
129 self.pos += bytes as u64;
130 Ok(bytes)
131 }
132}
133
134impl<I: WriteAt> Write for Cursor<I> {
135 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
136 let pos = self.pos;
137 let bytes = self.get_mut().write_at(pos, buf)?;
138 self.pos += bytes as u64;
139 Ok(bytes)
140 }
141
142 #[inline]
143 fn flush(&mut self) -> io::Result<()> {
144 WriteAt::flush(self.get_mut())
145 }
146}
147
148#[derive(Debug, Clone)]
162pub struct SizeCursor<I: Size> {
163 cursor: Cursor<I>,
164}
165
166impl<I: Size> SizeCursor<I> {
167 #[inline]
171 pub fn new_pos(io: I, pos: u64) -> Self {
172 SizeCursor {
173 cursor: Cursor::new_pos(io, pos)
174 }
175 }
176
177 #[inline]
181 pub fn new(io: I) -> Self {
182 SizeCursor {
183 cursor: Cursor::new(io)
184 }
185 }
186
187 #[inline]
188 pub fn as_cursor(&self) -> &Cursor<I> {
189 &self.cursor
190 }
191
192 #[inline]
193 pub fn as_cursor_mut(&mut self) -> &mut Cursor<I> {
194 &mut self.cursor
195 }
196
197 #[inline]
198 pub fn into_cursor(self) -> Cursor<I> {
199 self.cursor
200 }
201
202 #[inline]
203 pub fn into_inner(self) -> I {
204 self.cursor.io
205 }
206
207 #[inline]
208 pub fn get_ref(&self) -> &I {
209 &self.cursor.io
210 }
211
212 #[inline]
213 pub fn get_mut(&mut self) -> &mut I {
214 &mut self.cursor.io
215 }
216
217 #[inline]
218 pub fn position(&self) -> u64 {
219 self.cursor.position()
220 }
221
222 #[inline]
223 pub fn set_position(&mut self, pos: u64) {
224 self.cursor.set_position(pos)
225 }
226}
227
228impl<I: Size + ReadAt> Read for SizeCursor<I> {
229 #[inline]
230 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
231 self.cursor.read(buf)
232 }
233}
234
235impl<I: Size + WriteAt> Write for SizeCursor<I> {
236 #[inline]
237 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
238 self.cursor.write(buf)
239 }
240
241 #[inline]
242 fn flush(&mut self) -> io::Result<()> {
243 self.cursor.flush()
244 }
245}
246
247impl<I: Size> Seek for SizeCursor<I> {
249 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
250 let pos = match pos {
251 SeekFrom::Start(p) => p as i64,
252 SeekFrom::Current(p) => self.cursor.pos as i64 + p,
253 SeekFrom::End(p) => {
254 match self.get_ref().size() {
255 Err(e) => return Err(e),
256 Ok(None) => {
257 return Err(io::Error::new(io::ErrorKind::InvalidData, "seek from unknown end"))
258 }
259 Ok(Some(s)) => s as i64 + p,
260 }
261 }
262 };
263 self.cursor.pos = pos as u64;
264 Ok(self.cursor.pos)
265 }
266}