Skip to main content

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}