Skip to main content

core/io/
util.rs

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