Skip to main content

core/io/
util.rs

1use crate::io::{self, ErrorKind, IoSlice, Result, Seek, SeekFrom, SizeHint, Write};
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`]: crate::io::Write
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_write", since = "1.73.0")]
27impl Write for Empty {
28    #[inline]
29    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
30        Ok(buf.len())
31    }
32
33    #[inline]
34    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
35        let total_len = bufs.iter().map(|b| b.len()).sum();
36        Ok(total_len)
37    }
38
39    #[inline]
40    fn is_write_vectored(&self) -> bool {
41        true
42    }
43
44    #[inline]
45    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
46        Ok(())
47    }
48
49    #[inline]
50    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
51        Ok(())
52    }
53
54    #[inline]
55    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
56        Ok(())
57    }
58
59    #[inline]
60    fn flush(&mut self) -> io::Result<()> {
61        Ok(())
62    }
63}
64
65#[stable(feature = "empty_write", since = "1.73.0")]
66impl Write for &Empty {
67    #[inline]
68    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
69        Ok(buf.len())
70    }
71
72    #[inline]
73    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
74        let total_len = bufs.iter().map(|b| b.len()).sum();
75        Ok(total_len)
76    }
77
78    #[inline]
79    fn is_write_vectored(&self) -> bool {
80        true
81    }
82
83    #[inline]
84    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
85        Ok(())
86    }
87
88    #[inline]
89    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
90        Ok(())
91    }
92
93    #[inline]
94    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
95        Ok(())
96    }
97
98    #[inline]
99    fn flush(&mut self) -> io::Result<()> {
100        Ok(())
101    }
102}
103
104#[stable(feature = "empty_seek", since = "1.51.0")]
105impl Seek for Empty {
106    #[inline]
107    fn seek(&mut self, _pos: SeekFrom) -> Result<u64> {
108        Ok(0)
109    }
110
111    #[inline]
112    fn stream_len(&mut self) -> Result<u64> {
113        Ok(0)
114    }
115
116    #[inline]
117    fn stream_position(&mut self) -> Result<u64> {
118        Ok(0)
119    }
120}
121
122/// Creates a value that is always at EOF for reads, and ignores all data written.
123///
124/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
125/// and the contents of the buffer will not be inspected.
126///
127/// All calls to [`read`] from the returned reader will return [`Ok(0)`].
128///
129/// [`Ok(buf.len())`]: Ok
130/// [`Ok(0)`]: Ok
131///
132/// [`write`]: crate::io::Write::write
133/// [`read`]: ../../std/io/trait.Read.html#tymethod.read
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::empty().write(&buffer).unwrap();
142/// assert_eq!(num_bytes, 5);
143/// ```
144///
145///
146/// ```rust
147/// use std::io::{self, Read};
148///
149/// let mut buffer = String::new();
150/// io::empty().read_to_string(&mut buffer).unwrap();
151/// assert!(buffer.is_empty());
152/// ```
153#[must_use]
154#[stable(feature = "rust1", since = "1.0.0")]
155#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
156pub const fn empty() -> Empty {
157    Empty
158}
159
160/// A reader which yields one byte over and over and over and over and over and...
161///
162/// This struct is generally created by calling [`repeat()`]. Please
163/// see the documentation of [`repeat()`] for more details.
164#[stable(feature = "rust1", since = "1.0.0")]
165#[non_exhaustive]
166pub struct Repeat {
167    #[doc(hidden)]
168    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
169    pub byte: u8,
170}
171
172#[doc(hidden)]
173#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
174impl SizeHint for Repeat {
175    #[inline]
176    fn lower_bound(&self) -> usize {
177        usize::MAX
178    }
179
180    #[inline]
181    fn upper_bound(&self) -> Option<usize> {
182        None
183    }
184}
185
186/// Creates an instance of a reader that infinitely repeats one byte.
187///
188/// All reads from this reader will succeed by filling the specified buffer with
189/// the given byte.
190///
191/// # Examples
192///
193/// ```
194/// use std::io::{self, Read};
195///
196/// let mut buffer = [0; 3];
197/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
198/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
199/// ```
200#[must_use]
201#[stable(feature = "rust1", since = "1.0.0")]
202#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
203pub const fn repeat(byte: u8) -> Repeat {
204    Repeat { byte }
205}
206
207#[stable(feature = "std_debug", since = "1.16.0")]
208impl fmt::Debug for Repeat {
209    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210        f.debug_struct("Repeat").finish_non_exhaustive()
211    }
212}
213
214/// A writer which will move data into the void.
215///
216/// This struct is generally created by calling [`sink()`]. Please
217/// see the documentation of [`sink()`] for more details.
218#[stable(feature = "rust1", since = "1.0.0")]
219#[non_exhaustive]
220#[derive(Copy, Clone, Debug, Default)]
221pub struct Sink;
222
223#[stable(feature = "rust1", since = "1.0.0")]
224impl Write for Sink {
225    #[inline]
226    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
227        Ok(buf.len())
228    }
229
230    #[inline]
231    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
232        let total_len = bufs.iter().map(|b| b.len()).sum();
233        Ok(total_len)
234    }
235
236    #[inline]
237    fn is_write_vectored(&self) -> bool {
238        true
239    }
240
241    #[inline]
242    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
243        Ok(())
244    }
245
246    #[inline]
247    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
248        Ok(())
249    }
250
251    #[inline]
252    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
253        Ok(())
254    }
255
256    #[inline]
257    fn flush(&mut self) -> io::Result<()> {
258        Ok(())
259    }
260}
261
262#[stable(feature = "write_mt", since = "1.48.0")]
263impl Write for &Sink {
264    #[inline]
265    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
266        Ok(buf.len())
267    }
268
269    #[inline]
270    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
271        let total_len = bufs.iter().map(|b| b.len()).sum();
272        Ok(total_len)
273    }
274
275    #[inline]
276    fn is_write_vectored(&self) -> bool {
277        true
278    }
279
280    #[inline]
281    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
282        Ok(())
283    }
284
285    #[inline]
286    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
287        Ok(())
288    }
289
290    #[inline]
291    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
292        Ok(())
293    }
294
295    #[inline]
296    fn flush(&mut self) -> io::Result<()> {
297        Ok(())
298    }
299}
300
301/// Creates an instance of a writer which will successfully consume all data.
302///
303/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
304/// and the contents of the buffer will not be inspected.
305///
306/// [`write`]: crate::io::Write::write
307/// [`Ok(buf.len())`]: Ok
308///
309/// # Examples
310///
311/// ```rust
312/// use std::io::{self, Write};
313///
314/// let buffer = vec![1, 2, 3, 5, 8];
315/// let num_bytes = io::sink().write(&buffer).unwrap();
316/// assert_eq!(num_bytes, 5);
317/// ```
318#[must_use]
319#[stable(feature = "rust1", since = "1.0.0")]
320#[rustc_const_stable(feature = "const_io_structs", since = "1.79.0")]
321pub const fn sink() -> Sink {
322    Sink
323}
324
325/// Adapter to chain together two readers.
326///
327/// This struct is generally created by calling [`chain`] on a reader.
328/// Please see the documentation of [`chain`] for more details.
329///
330/// [`chain`]: ../../std/io/trait.Read.html#method.chain
331#[stable(feature = "rust1", since = "1.0.0")]
332#[derive(Debug)]
333#[non_exhaustive]
334pub struct Chain<T, U> {
335    #[doc(hidden)]
336    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
337    pub first: T,
338    #[doc(hidden)]
339    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
340    pub second: U,
341    #[doc(hidden)]
342    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
343    pub done_first: bool,
344}
345
346#[doc(hidden)]
347#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
348impl<T, U> SizeHint for Chain<T, U> {
349    #[inline]
350    fn lower_bound(&self) -> usize {
351        SizeHint::lower_bound(&self.first) + SizeHint::lower_bound(&self.second)
352    }
353
354    #[inline]
355    fn upper_bound(&self) -> Option<usize> {
356        match (SizeHint::upper_bound(&self.first), SizeHint::upper_bound(&self.second)) {
357            (Some(first), Some(second)) => first.checked_add(second),
358            _ => None,
359        }
360    }
361}
362
363impl<T, U> Chain<T, U> {
364    /// Consumes the `Chain`, returning the wrapped readers.
365    ///
366    /// # Examples
367    ///
368    /// ```no_run
369    /// use std::io;
370    /// use std::io::prelude::*;
371    /// use std::fs::File;
372    ///
373    /// fn main() -> io::Result<()> {
374    ///     let mut foo_file = File::open("foo.txt")?;
375    ///     let mut bar_file = File::open("bar.txt")?;
376    ///
377    ///     let chain = foo_file.chain(bar_file);
378    ///     let (foo_file, bar_file) = chain.into_inner();
379    ///     Ok(())
380    /// }
381    /// ```
382    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
383    pub fn into_inner(self) -> (T, U) {
384        (self.first, self.second)
385    }
386
387    /// Gets references to the underlying readers in this `Chain`.
388    ///
389    /// Care should be taken to avoid modifying the internal I/O state of the
390    /// underlying readers as doing so may corrupt the internal state of this
391    /// `Chain`.
392    ///
393    /// # Examples
394    ///
395    /// ```no_run
396    /// use std::io;
397    /// use std::io::prelude::*;
398    /// use std::fs::File;
399    ///
400    /// fn main() -> io::Result<()> {
401    ///     let mut foo_file = File::open("foo.txt")?;
402    ///     let mut bar_file = File::open("bar.txt")?;
403    ///
404    ///     let chain = foo_file.chain(bar_file);
405    ///     let (foo_file, bar_file) = chain.get_ref();
406    ///     Ok(())
407    /// }
408    /// ```
409    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
410    pub fn get_ref(&self) -> (&T, &U) {
411        (&self.first, &self.second)
412    }
413
414    /// Gets mutable references to the underlying readers in this `Chain`.
415    ///
416    /// Care should be taken to avoid modifying the internal I/O state of the
417    /// underlying readers as doing so may corrupt the internal state of this
418    /// `Chain`.
419    ///
420    /// # Examples
421    ///
422    /// ```no_run
423    /// use std::io;
424    /// use std::io::prelude::*;
425    /// use std::fs::File;
426    ///
427    /// fn main() -> io::Result<()> {
428    ///     let mut foo_file = File::open("foo.txt")?;
429    ///     let mut bar_file = File::open("bar.txt")?;
430    ///
431    ///     let mut chain = foo_file.chain(bar_file);
432    ///     let (foo_file, bar_file) = chain.get_mut();
433    ///     Ok(())
434    /// }
435    /// ```
436    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
437    pub fn get_mut(&mut self) -> (&mut T, &mut U) {
438        (&mut self.first, &mut self.second)
439    }
440}
441
442#[doc(hidden)]
443#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
444#[must_use]
445#[inline]
446pub const fn chain<T, U>(first: T, second: U) -> Chain<T, U> {
447    Chain { first, second, done_first: false }
448}
449
450/// Reader adapter which limits the bytes read from an underlying reader.
451///
452/// This struct is generally created by calling [`take`] on a reader.
453/// Please see the documentation of [`take`] for more details.
454///
455/// [`take`]: ../../std/io/trait.Read.html#method.take
456#[stable(feature = "rust1", since = "1.0.0")]
457#[derive(Debug)]
458#[non_exhaustive]
459pub struct Take<T> {
460    #[doc(hidden)]
461    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
462    pub inner: T,
463    #[doc(hidden)]
464    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
465    pub len: u64,
466    #[doc(hidden)]
467    #[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
468    pub limit: u64,
469}
470
471#[doc(hidden)]
472#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
473impl<T> SizeHint for Take<T> {
474    #[inline]
475    fn lower_bound(&self) -> usize {
476        cmp::min(SizeHint::lower_bound(&self.inner) as u64, self.limit) as usize
477    }
478
479    #[inline]
480    fn upper_bound(&self) -> Option<usize> {
481        match SizeHint::upper_bound(&self.inner) {
482            Some(upper_bound) => Some(cmp::min(upper_bound as u64, self.limit) as usize),
483            None => self.limit.try_into().ok(),
484        }
485    }
486}
487
488impl<T> Take<T> {
489    /// Returns the number of bytes that can be read before this instance will
490    /// return EOF.
491    ///
492    /// # Note
493    ///
494    /// This instance may reach `EOF` after reading fewer bytes than indicated by
495    /// this method if the underlying [`Read`] instance reaches EOF.
496    ///
497    /// [`Read`]: ../../std/io/trait.Read.html
498    ///
499    /// # Examples
500    ///
501    /// ```no_run
502    /// use std::io;
503    /// use std::io::prelude::*;
504    /// use std::fs::File;
505    ///
506    /// fn main() -> io::Result<()> {
507    ///     let f = File::open("foo.txt")?;
508    ///
509    ///     // read at most five bytes
510    ///     let handle = f.take(5);
511    ///
512    ///     println!("limit: {}", handle.limit());
513    ///     Ok(())
514    /// }
515    /// ```
516    #[stable(feature = "rust1", since = "1.0.0")]
517    pub fn limit(&self) -> u64 {
518        self.limit
519    }
520
521    /// Returns the number of bytes read so far.
522    #[unstable(feature = "seek_io_take_position", issue = "97227")]
523    #[inline]
524    pub fn position(&self) -> u64 {
525        self.len - self.limit
526    }
527
528    /// Sets the number of bytes that can be read before this instance will
529    /// return EOF. This is the same as constructing a new `Take` instance, so
530    /// the amount of bytes read and the previous limit value don't matter when
531    /// calling this method.
532    ///
533    /// # Examples
534    ///
535    /// ```no_run
536    /// use std::io;
537    /// use std::io::prelude::*;
538    /// use std::fs::File;
539    ///
540    /// fn main() -> io::Result<()> {
541    ///     let f = File::open("foo.txt")?;
542    ///
543    ///     // read at most five bytes
544    ///     let mut handle = f.take(5);
545    ///     handle.set_limit(10);
546    ///
547    ///     assert_eq!(handle.limit(), 10);
548    ///     Ok(())
549    /// }
550    /// ```
551    #[stable(feature = "take_set_limit", since = "1.27.0")]
552    pub fn set_limit(&mut self, limit: u64) {
553        self.len = limit;
554        self.limit = limit;
555    }
556
557    /// Consumes the `Take`, returning the wrapped reader.
558    ///
559    /// # Examples
560    ///
561    /// ```no_run
562    /// use std::io;
563    /// use std::io::prelude::*;
564    /// use std::fs::File;
565    ///
566    /// fn main() -> io::Result<()> {
567    ///     let mut file = File::open("foo.txt")?;
568    ///
569    ///     let mut buffer = [0; 5];
570    ///     let mut handle = file.take(5);
571    ///     handle.read(&mut buffer)?;
572    ///
573    ///     let file = handle.into_inner();
574    ///     Ok(())
575    /// }
576    /// ```
577    #[stable(feature = "io_take_into_inner", since = "1.15.0")]
578    pub fn into_inner(self) -> T {
579        self.inner
580    }
581
582    /// Gets a reference to the underlying reader.
583    ///
584    /// Care should be taken to avoid modifying the internal I/O state of the
585    /// underlying reader as doing so may corrupt the internal limit of this
586    /// `Take`.
587    ///
588    /// # Examples
589    ///
590    /// ```no_run
591    /// use std::io;
592    /// use std::io::prelude::*;
593    /// use std::fs::File;
594    ///
595    /// fn main() -> io::Result<()> {
596    ///     let mut file = File::open("foo.txt")?;
597    ///
598    ///     let mut buffer = [0; 5];
599    ///     let mut handle = file.take(5);
600    ///     handle.read(&mut buffer)?;
601    ///
602    ///     let file = handle.get_ref();
603    ///     Ok(())
604    /// }
605    /// ```
606    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
607    pub fn get_ref(&self) -> &T {
608        &self.inner
609    }
610
611    /// Gets a mutable reference to the underlying reader.
612    ///
613    /// Care should be taken to avoid modifying the internal I/O state of the
614    /// underlying reader as doing so may corrupt the internal limit of this
615    /// `Take`.
616    ///
617    /// # Examples
618    ///
619    /// ```no_run
620    /// use std::io;
621    /// use std::io::prelude::*;
622    /// use std::fs::File;
623    ///
624    /// fn main() -> io::Result<()> {
625    ///     let mut file = File::open("foo.txt")?;
626    ///
627    ///     let mut buffer = [0; 5];
628    ///     let mut handle = file.take(5);
629    ///     handle.read(&mut buffer)?;
630    ///
631    ///     let file = handle.get_mut();
632    ///     Ok(())
633    /// }
634    /// ```
635    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
636    pub fn get_mut(&mut self) -> &mut T {
637        &mut self.inner
638    }
639}
640
641#[stable(feature = "seek_io_take", since = "1.89.0")]
642impl<T: Seek> Seek for Take<T> {
643    fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
644        let new_position = match pos {
645            SeekFrom::Start(v) => Some(v),
646            SeekFrom::Current(v) => self.position().checked_add_signed(v),
647            SeekFrom::End(v) => self.len.checked_add_signed(v),
648        };
649        let new_position = match new_position {
650            Some(v) if v <= self.len => v,
651            _ => return Err(ErrorKind::InvalidInput.into()),
652        };
653        while new_position != self.position() {
654            if let Some(offset) = new_position.checked_signed_diff(self.position()) {
655                self.inner.seek_relative(offset)?;
656                self.limit = self.limit.wrapping_sub(offset as u64);
657                break;
658            }
659            let offset = if new_position > self.position() { i64::MAX } else { i64::MIN };
660            self.inner.seek_relative(offset)?;
661            self.limit = self.limit.wrapping_sub(offset as u64);
662        }
663        Ok(new_position)
664    }
665
666    fn stream_len(&mut self) -> Result<u64> {
667        Ok(self.len)
668    }
669
670    fn stream_position(&mut self) -> Result<u64> {
671        Ok(self.position())
672    }
673
674    fn seek_relative(&mut self, offset: i64) -> Result<()> {
675        if !self.position().checked_add_signed(offset).is_some_and(|p| p <= self.len) {
676            return Err(ErrorKind::InvalidInput.into());
677        }
678        self.inner.seek_relative(offset)?;
679        self.limit = self.limit.wrapping_sub(offset as u64);
680        Ok(())
681    }
682}
683
684#[doc(hidden)]
685#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
686#[must_use]
687#[inline]
688pub const fn take<T>(inner: T, limit: u64) -> Take<T> {
689    Take { inner, limit, len: limit }
690}