Skip to main content

core/io/
util.rs

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