ndless/file_io/io/
util.rs1#![allow(missing_copy_implementations)]
2
3use crate::io::{self, BufRead, ErrorKind, Initializer, IoSlice, IoSliceMut, Read, Write};
4use core::fmt;
5use core::mem::MaybeUninit;
6
7pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
43where
44 R: Read,
45 W: Write,
46{
47 let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit();
48 unsafe {
57 reader.initializer().initialize(buf.assume_init_mut());
58 }
59
60 let mut written = 0;
61 loop {
62 let len = match reader.read(unsafe { buf.assume_init_mut() }) {
63 Ok(0) => return Ok(written),
64 Ok(len) => len,
65 Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
66 Err(e) => return Err(e),
67 };
68 writer.write_all(unsafe { &buf.assume_init_ref()[..len] })?;
69 written += len as u64;
70 }
71}
72
73pub struct Empty {
80 _priv: (),
81}
82
83pub fn empty() -> Empty {
101 Empty { _priv: () }
102}
103
104impl Read for Empty {
105 #[inline]
106 fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
107 Ok(0)
108 }
109
110 #[inline]
111 unsafe fn initializer(&self) -> Initializer {
112 Initializer::nop()
113 }
114}
115impl BufRead for Empty {
116 #[inline]
117 fn fill_buf(&mut self) -> io::Result<&[u8]> {
118 Ok(&[])
119 }
120 #[inline]
121 fn consume(&mut self, _n: usize) {}
122}
123
124impl fmt::Debug for Empty {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 f.pad("Empty { .. }")
127 }
128}
129
130pub struct Repeat {
137 byte: u8,
138}
139
140pub fn repeat(byte: u8) -> Repeat {
155 Repeat { byte }
156}
157
158impl Read for Repeat {
159 #[inline]
160 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
161 for slot in &mut *buf {
162 *slot = self.byte;
163 }
164 Ok(buf.len())
165 }
166
167 #[inline]
168 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
169 let mut nwritten = 0;
170 for buf in bufs {
171 nwritten += self.read(buf)?;
172 }
173 Ok(nwritten)
174 }
175
176 #[inline]
177 unsafe fn initializer(&self) -> Initializer {
178 Initializer::nop()
179 }
180}
181
182impl fmt::Debug for Repeat {
183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184 f.pad("Repeat { .. }")
185 }
186}
187
188pub struct Sink {
195 _priv: (),
196}
197
198pub fn sink() -> Sink {
213 Sink { _priv: () }
214}
215
216impl Write for Sink {
217 #[inline]
218 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
219 Ok(buf.len())
220 }
221
222 #[inline]
223 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
224 let total_len = bufs.iter().map(|b| b.len()).sum();
225 Ok(total_len)
226 }
227
228 #[inline]
229 fn flush(&mut self) -> io::Result<()> {
230 Ok(())
231 }
232}
233
234impl fmt::Debug for Sink {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 f.pad("Sink { .. }")
237 }
238}
239
240#[cfg(test)]
241mod tests {
242 use crate::io::prelude::*;
243 use crate::io::{copy, empty, repeat, sink};
244
245 #[test]
246 fn copy_copies() {
247 let mut r = repeat(0).take(4);
248 let mut w = sink();
249 assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
250
251 let mut r = repeat(0).take(1 << 17);
252 assert_eq!(
253 copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(),
254 1 << 17
255 );
256 }
257
258 #[test]
259 fn sink_sinks() {
260 let mut s = sink();
261 assert_eq!(s.write(&[]).unwrap(), 0);
262 assert_eq!(s.write(&[0]).unwrap(), 1);
263 assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
264 assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
265 }
266
267 #[test]
268 fn empty_reads() {
269 let mut e = empty();
270 assert_eq!(e.read(&mut []).unwrap(), 0);
271 assert_eq!(e.read(&mut [0]).unwrap(), 0);
272 assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
273 assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
274 }
275
276 #[test]
277 fn repeat_repeats() {
278 let mut r = repeat(4);
279 let mut b = [0; 1024];
280 assert_eq!(r.read(&mut b).unwrap(), 1024);
281 assert!(b.iter().all(|b| *b == 4));
282 }
283
284 #[test]
285 fn take_some_bytes() {
286 assert_eq!(repeat(4).take(100).bytes().count(), 100);
287 assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4);
288 assert_eq!(
289 repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(),
290 20
291 );
292 }
293}