core/io/util.rs
1use crate::io::{ErrorKind, Result, Seek, SeekFrom, SizeHint};
2use crate::{cmp, fmt};
3
4/// `Empty` ignores any data written via [`Write`], and will always be empty
5/// (returning zero bytes) when read via [`Read`].
6///
7/// [`Write`]: ../../std/io/trait.Write.html
8/// [`Read`]: ../../std/io/trait.Read.html
9///
10/// This struct is generally created by calling [`empty()`]. Please
11/// see the documentation of [`empty()`] for more details.
12#[stable(feature = "rust1", since = "1.0.0")]
13#[non_exhaustive]
14#[derive(Copy, Clone, Debug, Default)]
15pub struct Empty;
16
17#[doc(hidden)]
18#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
19impl SizeHint for Empty {
20 #[inline]
21 fn upper_bound(&self) -> Option<usize> {
22 Some(0)
23 }
24}
25
26#[stable(feature = "empty_seek", since = "1.51.0")]
27impl Seek for Empty {
28 #[inline]
29 fn seek(&mut self, _pos: SeekFrom) -> Result<u64> {
30 Ok(0)
31 }
32
33 #[inline]
34 fn stream_len(&mut self) -> Result<u64> {
35 Ok(0)
36 }
37
38 #[inline]
39 fn stream_position(&mut self) -> Result<u64> {
40 Ok(0)
41 }
42}
43
44/// Creates a value that is always at EOF for reads, and ignores all data written.
45///
46/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
47/// and the contents of the buffer will not be inspected.
48///
49/// All calls to [`read`] from the returned reader will return [`Ok(0)`].
50///
51/// [`Ok(buf.len())`]: Ok
52/// [`Ok(0)`]: Ok
53///
54/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
55/// [`read`]: ../../std/io/trait.Read.html#tymethod.read
56///
57/// # Examples
58///
59/// ```rust
60/// use std::io::{self, Write};
61///
62/// let buffer = vec![1, 2, 3, 5, 8];
63/// let num_bytes = io::empty().write(&buffer).unwrap();
64/// assert_eq!(num_bytes, 5);
65/// ```
66///
67///
68/// ```rust
69/// use std::io::{self, Read};
70///
71/// let mut buffer = String::new();
72/// io::empty().read_to_string(&mut buffer).unwrap();
73/// assert!(buffer.is_empty());
74/// ```
75#[must_use]
76#[stable(feature = "rust1", since = "1.0.0")]
77#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
78pub const fn empty() -> Empty {
79 Empty
80}
81
82/// A reader which yields one byte over and over and over and over and over and...
83///
84/// This struct is generally created by calling [`repeat()`]. Please
85/// see the documentation of [`repeat()`] for more details.
86#[stable(feature = "rust1", since = "1.0.0")]
87#[non_exhaustive]
88pub struct Repeat {
89 #[doc(hidden)]
90 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
91 pub byte: u8,
92}
93
94#[doc(hidden)]
95#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
96impl SizeHint for Repeat {
97 #[inline]
98 fn lower_bound(&self) -> usize {
99 usize::MAX
100 }
101
102 #[inline]
103 fn upper_bound(&self) -> Option<usize> {
104 None
105 }
106}
107
108/// Creates an instance of a reader that infinitely repeats one byte.
109///
110/// All reads from this reader will succeed by filling the specified buffer with
111/// the given byte.
112///
113/// # Examples
114///
115/// ```
116/// use std::io::{self, Read};
117///
118/// let mut buffer = [0; 3];
119/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
120/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
121/// ```
122#[must_use]
123#[stable(feature = "rust1", since = "1.0.0")]
124#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
125pub const fn repeat(byte: u8) -> Repeat {
126 Repeat { byte }
127}
128
129#[stable(feature = "std_debug", since = "1.16.0")]
130impl fmt::Debug for Repeat {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 f.debug_struct("Repeat").finish_non_exhaustive()
133 }
134}
135
136/// A writer which will move data into the void.
137///
138/// This struct is generally created by calling [`sink()`]. Please
139/// see the documentation of [`sink()`] for more details.
140#[stable(feature = "rust1", since = "1.0.0")]
141#[non_exhaustive]
142#[derive(Copy, Clone, Debug, Default)]
143pub struct Sink;
144
145/// Creates an instance of a writer which will successfully consume all data.
146///
147/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
148/// and the contents of the buffer will not be inspected.
149///
150/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
151/// [`Ok(buf.len())`]: Ok
152///
153/// # Examples
154///
155/// ```rust
156/// use std::io::{self, Write};
157///
158/// let buffer = vec![1, 2, 3, 5, 8];
159/// let num_bytes = io::sink().write(&buffer).unwrap();
160/// assert_eq!(num_bytes, 5);
161/// ```
162#[must_use]
163#[stable(feature = "rust1", since = "1.0.0")]
164#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
165pub const fn sink() -> Sink {
166 Sink
167}
168
169/// Adapter to chain together two readers.
170///
171/// This struct is generally created by calling [`chain`] on a reader.
172/// Please see the documentation of [`chain`] for more details.
173///
174/// [`chain`]: ../../std/io/trait.Read.html#method.chain
175#[stable(feature = "rust1", since = "1.0.0")]
176#[derive(Debug)]
177#[non_exhaustive]
178pub struct Chain<T, U> {
179 #[doc(hidden)]
180 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
181 pub first: T,
182 #[doc(hidden)]
183 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
184 pub second: U,
185 #[doc(hidden)]
186 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
187 pub done_first: bool,
188}
189
190#[doc(hidden)]
191#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
192impl<T, U> SizeHint for Chain<T, U> {
193 #[inline]
194 fn lower_bound(&self) -> usize {
195 SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
196 }
197
198 #[inline]
199 fn upper_bound(&self) -> Option<usize> {
200 match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
201 (Some(first), Some(second)) => first.checked_add(second),
202 _ => None,
203 }
204 }
205}
206
207impl<T, U> Chain<T, U> {
208 /// Consumes the `Chain`, returning the wrapped readers.
209 ///
210 /// # Examples
211 ///
212 /// ```no_run
213 /// use std::io;
214 /// use std::io::prelude::*;
215 /// use std::fs::File;
216 ///
217 /// fn main() -> io::Result<()> {
218 /// let mut foo_file = File::open("foo.txt")?;
219 /// let mut bar_file = File::open("bar.txt")?;
220 ///
221 /// let chain = foo_file.chain(bar_file);
222 /// let (foo_file, bar_file) = chain.into_inner();
223 /// Ok(())
224 /// }
225 /// ```
226 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
227 pub fn into_inner(self) -> (T, U) {
228 (self.first, self.second)
229 }
230
231 /// Gets references to the underlying readers in this `Chain`.
232 ///
233 /// Care should be taken to avoid modifying the internal I/O state of the
234 /// underlying readers as doing so may corrupt the internal state of this
235 /// `Chain`.
236 ///
237 /// # Examples
238 ///
239 /// ```no_run
240 /// use std::io;
241 /// use std::io::prelude::*;
242 /// use std::fs::File;
243 ///
244 /// fn main() -> io::Result<()> {
245 /// let mut foo_file = File::open("foo.txt")?;
246 /// let mut bar_file = File::open("bar.txt")?;
247 ///
248 /// let chain = foo_file.chain(bar_file);
249 /// let (foo_file, bar_file) = chain.get_ref();
250 /// Ok(())
251 /// }
252 /// ```
253 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
254 pub fn get_ref(&self) -> (&T, &U) {
255 (&self.first, &self.second)
256 }
257
258 /// Gets mutable references to the underlying readers in this `Chain`.
259 ///
260 /// Care should be taken to avoid modifying the internal I/O state of the
261 /// underlying readers as doing so may corrupt the internal state of this
262 /// `Chain`.
263 ///
264 /// # Examples
265 ///
266 /// ```no_run
267 /// use std::io;
268 /// use std::io::prelude::*;
269 /// use std::fs::File;
270 ///
271 /// fn main() -> io::Result<()> {
272 /// let mut foo_file = File::open("foo.txt")?;
273 /// let mut bar_file = File::open("bar.txt")?;
274 ///
275 /// let mut chain = foo_file.chain(bar_file);
276 /// let (foo_file, bar_file) = chain.get_mut();
277 /// Ok(())
278 /// }
279 /// ```
280 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
281 pub fn get_mut(&mut self) -> (&mut T, &mut U) {
282 (&mut self.first, &mut self.second)
283 }
284}
285
286#[doc(hidden)]
287#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
288#[must_use]
289#[inline]
290pub const fn chain<T, U>(first: T, second: U) -> Chain<T, U> {
291 Chain { first, second, done_first: false }
292}
293
294/// Reader adapter which limits the bytes read from an underlying reader.
295///
296/// This struct is generally created by calling [`take`] on a reader.
297/// Please see the documentation of [`take`] for more details.
298///
299/// [`take`]: ../../std/io/trait.Read.html#method.take
300#[stable(feature = "rust1", since = "1.0.0")]
301#[derive(Debug)]
302#[non_exhaustive]
303pub struct Take<T> {
304 #[doc(hidden)]
305 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
306 pub inner: T,
307 #[doc(hidden)]
308 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
309 pub len: u64,
310 #[doc(hidden)]
311 #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
312 pub limit: u64,
313}
314
315#[doc(hidden)]
316#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
317impl<T> SizeHint for Take<T> {
318 #[inline]
319 fn lower_bound(&self) -> usize {
320 cmp::min(SizeHint::lower_bound(&self.inner) as u64, self.limit) as usize
321 }
322
323 #[inline]
324 fn upper_bound(&self) -> Option<usize> {
325 match SizeHint::upper_bound(&self.inner) {
326 Some(upper_bound) => Some(cmp::min(upper_bound as u64, self.limit) as usize),
327 None => self.limit.try_into().ok(),
328 }
329 }
330}
331
332impl<T> Take<T> {
333 /// Returns the number of bytes that can be read before this instance will
334 /// return EOF.
335 ///
336 /// # Note
337 ///
338 /// This instance may reach `EOF` after reading fewer bytes than indicated by
339 /// this method if the underlying [`Read`] instance reaches EOF.
340 ///
341 /// [`Read`]: ../../std/io/trait.Read.html
342 ///
343 /// # Examples
344 ///
345 /// ```no_run
346 /// use std::io;
347 /// use std::io::prelude::*;
348 /// use std::fs::File;
349 ///
350 /// fn main() -> io::Result<()> {
351 /// let f = File::open("foo.txt")?;
352 ///
353 /// // read at most five bytes
354 /// let handle = f.take(5);
355 ///
356 /// println!("limit: {}", handle.limit());
357 /// Ok(())
358 /// }
359 /// ```
360 #[stable(feature = "rust1", since = "1.0.0")]
361 pub fn limit(&self) -> u64 {
362 self.limit
363 }
364
365 /// Returns the number of bytes read so far.
366 #[unstable(feature = "seek_io_take_position", issue = "97227")]
367 #[inline]
368 pub fn position(&self) -> u64 {
369 self.len - self.limit
370 }
371
372 /// Sets the number of bytes that can be read before this instance will
373 /// return EOF. This is the same as constructing a new `Take` instance, so
374 /// the amount of bytes read and the previous limit value don't matter when
375 /// calling this method.
376 ///
377 /// # Examples
378 ///
379 /// ```no_run
380 /// use std::io;
381 /// use std::io::prelude::*;
382 /// use std::fs::File;
383 ///
384 /// fn main() -> io::Result<()> {
385 /// let f = File::open("foo.txt")?;
386 ///
387 /// // read at most five bytes
388 /// let mut handle = f.take(5);
389 /// handle.set_limit(10);
390 ///
391 /// assert_eq!(handle.limit(), 10);
392 /// Ok(())
393 /// }
394 /// ```
395 #[stable(feature = "take_set_limit", since = "1.27.0")]
396 pub fn set_limit(&mut self, limit: u64) {
397 self.len = limit;
398 self.limit = limit;
399 }
400
401 /// Consumes the `Take`, returning the wrapped reader.
402 ///
403 /// # Examples
404 ///
405 /// ```no_run
406 /// use std::io;
407 /// use std::io::prelude::*;
408 /// use std::fs::File;
409 ///
410 /// fn main() -> io::Result<()> {
411 /// let mut file = File::open("foo.txt")?;
412 ///
413 /// let mut buffer = [0; 5];
414 /// let mut handle = file.take(5);
415 /// handle.read(&mut buffer)?;
416 ///
417 /// let file = handle.into_inner();
418 /// Ok(())
419 /// }
420 /// ```
421 #[stable(feature = "io_take_into_inner", since = "1.15.0")]
422 pub fn into_inner(self) -> T {
423 self.inner
424 }
425
426 /// Gets a reference to the underlying reader.
427 ///
428 /// Care should be taken to avoid modifying the internal I/O state of the
429 /// underlying reader as doing so may corrupt the internal limit of this
430 /// `Take`.
431 ///
432 /// # Examples
433 ///
434 /// ```no_run
435 /// use std::io;
436 /// use std::io::prelude::*;
437 /// use std::fs::File;
438 ///
439 /// fn main() -> io::Result<()> {
440 /// let mut file = File::open("foo.txt")?;
441 ///
442 /// let mut buffer = [0; 5];
443 /// let mut handle = file.take(5);
444 /// handle.read(&mut buffer)?;
445 ///
446 /// let file = handle.get_ref();
447 /// Ok(())
448 /// }
449 /// ```
450 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
451 pub fn get_ref(&self) -> &T {
452 &self.inner
453 }
454
455 /// Gets a mutable reference to the underlying reader.
456 ///
457 /// Care should be taken to avoid modifying the internal I/O state of the
458 /// underlying reader as doing so may corrupt the internal limit of this
459 /// `Take`.
460 ///
461 /// # Examples
462 ///
463 /// ```no_run
464 /// use std::io;
465 /// use std::io::prelude::*;
466 /// use std::fs::File;
467 ///
468 /// fn main() -> io::Result<()> {
469 /// let mut file = File::open("foo.txt")?;
470 ///
471 /// let mut buffer = [0; 5];
472 /// let mut handle = file.take(5);
473 /// handle.read(&mut buffer)?;
474 ///
475 /// let file = handle.get_mut();
476 /// Ok(())
477 /// }
478 /// ```
479 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
480 pub fn get_mut(&mut self) -> &mut T {
481 &mut self.inner
482 }
483}
484
485#[stable(feature = "seek_io_take", since = "1.89.0")]
486impl<T: Seek> Seek for Take<T> {
487 fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
488 let new_position = match pos {
489 SeekFrom::Start(v) => Some(v),
490 SeekFrom::Current(v) => self.position().checked_add_signed(v),
491 SeekFrom::End(v) => self.len.checked_add_signed(v),
492 };
493 let new_position = match new_position {
494 Some(v) if v <= self.len => v,
495 _ => return Err(ErrorKind::InvalidInput.into()),
496 };
497 while new_position != self.position() {
498 if let Some(offset) = new_position.checked_signed_diff(self.position()) {
499 self.inner.seek_relative(offset)?;
500 self.limit = self.limit.wrapping_sub(offset as u64);
501 break;
502 }
503 let offset = if new_position > self.position() { i64::MAX } else { i64::MIN };
504 self.inner.seek_relative(offset)?;
505 self.limit = self.limit.wrapping_sub(offset as u64);
506 }
507 Ok(new_position)
508 }
509
510 fn stream_len(&mut self) -> Result<u64> {
511 Ok(self.len)
512 }
513
514 fn stream_position(&mut self) -> Result<u64> {
515 Ok(self.position())
516 }
517
518 fn seek_relative(&mut self, offset: i64) -> Result<()> {
519 if !self.position().checked_add_signed(offset).is_some_and(|p| p <= self.len) {
520 return Err(ErrorKind::InvalidInput.into());
521 }
522 self.inner.seek_relative(offset)?;
523 self.limit = self.limit.wrapping_sub(offset as u64);
524 Ok(())
525 }
526}
527
528#[doc(hidden)]
529#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
530#[must_use]
531#[inline]
532pub const fn take<T>(inner: T, limit: u64) -> Take<T> {
533 Take { inner, limit, len: limit }
534}