]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/util.rs
Auto merge of #105582 - saethlin:instcombine-assert-inhabited, r=cjgillot
[rust.git] / library / std / src / io / util.rs
1 #![allow(missing_copy_implementations)]
2
3 #[cfg(test)]
4 mod tests;
5
6 use crate::fmt;
7 use crate::io::{
8     self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
9 };
10
11 /// A reader which is always at EOF.
12 ///
13 /// This struct is generally created by calling [`empty()`]. Please see
14 /// the documentation of [`empty()`] for more details.
15 #[stable(feature = "rust1", since = "1.0.0")]
16 #[non_exhaustive]
17 #[derive(Copy, Clone, Default)]
18 pub struct Empty;
19
20 /// Constructs a new handle to an empty reader.
21 ///
22 /// All reads from the returned reader will return <code>[Ok]\(0)</code>.
23 ///
24 /// # Examples
25 ///
26 /// A slightly sad example of not reading anything into a buffer:
27 ///
28 /// ```
29 /// use std::io::{self, Read};
30 ///
31 /// let mut buffer = String::new();
32 /// io::empty().read_to_string(&mut buffer).unwrap();
33 /// assert!(buffer.is_empty());
34 /// ```
35 #[must_use]
36 #[stable(feature = "rust1", since = "1.0.0")]
37 #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
38 pub const fn empty() -> Empty {
39     Empty
40 }
41
42 #[stable(feature = "rust1", since = "1.0.0")]
43 impl Read for Empty {
44     #[inline]
45     fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
46         Ok(0)
47     }
48
49     #[inline]
50     fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
51         Ok(())
52     }
53 }
54 #[stable(feature = "rust1", since = "1.0.0")]
55 impl BufRead for Empty {
56     #[inline]
57     fn fill_buf(&mut self) -> io::Result<&[u8]> {
58         Ok(&[])
59     }
60     #[inline]
61     fn consume(&mut self, _n: usize) {}
62 }
63
64 #[stable(feature = "empty_seek", since = "1.51.0")]
65 impl Seek for Empty {
66     fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> {
67         Ok(0)
68     }
69
70     fn stream_len(&mut self) -> io::Result<u64> {
71         Ok(0)
72     }
73
74     fn stream_position(&mut self) -> io::Result<u64> {
75         Ok(0)
76     }
77 }
78
79 #[stable(feature = "std_debug", since = "1.16.0")]
80 impl fmt::Debug for Empty {
81     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82         f.debug_struct("Empty").finish_non_exhaustive()
83     }
84 }
85
86 impl SizeHint for Empty {
87     #[inline]
88     fn upper_bound(&self) -> Option<usize> {
89         Some(0)
90     }
91 }
92
93 /// A reader which yields one byte over and over and over and over and over and...
94 ///
95 /// This struct is generally created by calling [`repeat()`]. Please
96 /// see the documentation of [`repeat()`] for more details.
97 #[stable(feature = "rust1", since = "1.0.0")]
98 pub struct Repeat {
99     byte: u8,
100 }
101
102 /// Creates an instance of a reader that infinitely repeats one byte.
103 ///
104 /// All reads from this reader will succeed by filling the specified buffer with
105 /// the given byte.
106 ///
107 /// # Examples
108 ///
109 /// ```
110 /// use std::io::{self, Read};
111 ///
112 /// let mut buffer = [0; 3];
113 /// io::repeat(0b101).read_exact(&mut buffer).unwrap();
114 /// assert_eq!(buffer, [0b101, 0b101, 0b101]);
115 /// ```
116 #[must_use]
117 #[stable(feature = "rust1", since = "1.0.0")]
118 #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
119 pub const fn repeat(byte: u8) -> Repeat {
120     Repeat { byte }
121 }
122
123 #[stable(feature = "rust1", since = "1.0.0")]
124 impl Read for Repeat {
125     #[inline]
126     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
127         for slot in &mut *buf {
128             *slot = self.byte;
129         }
130         Ok(buf.len())
131     }
132
133     fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
134         // SAFETY: No uninit bytes are being written
135         for slot in unsafe { buf.as_mut() } {
136             slot.write(self.byte);
137         }
138
139         let remaining = buf.capacity();
140
141         // SAFETY: the entire unfilled portion of buf has been initialized
142         unsafe {
143             buf.advance(remaining);
144         }
145
146         Ok(())
147     }
148
149     #[inline]
150     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
151         let mut nwritten = 0;
152         for buf in bufs {
153             nwritten += self.read(buf)?;
154         }
155         Ok(nwritten)
156     }
157
158     #[inline]
159     fn is_read_vectored(&self) -> bool {
160         true
161     }
162 }
163
164 impl SizeHint for Repeat {
165     #[inline]
166     fn lower_bound(&self) -> usize {
167         usize::MAX
168     }
169
170     #[inline]
171     fn upper_bound(&self) -> Option<usize> {
172         None
173     }
174 }
175
176 #[stable(feature = "std_debug", since = "1.16.0")]
177 impl fmt::Debug for Repeat {
178     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179         f.debug_struct("Repeat").finish_non_exhaustive()
180     }
181 }
182
183 /// A writer which will move data into the void.
184 ///
185 /// This struct is generally created by calling [`sink`]. Please
186 /// see the documentation of [`sink()`] for more details.
187 #[stable(feature = "rust1", since = "1.0.0")]
188 #[non_exhaustive]
189 #[derive(Copy, Clone, Default)]
190 pub struct Sink;
191
192 /// Creates an instance of a writer which will successfully consume all data.
193 ///
194 /// All calls to [`write`] on the returned instance will return `Ok(buf.len())`
195 /// and the contents of the buffer will not be inspected.
196 ///
197 /// [`write`]: Write::write
198 ///
199 /// # Examples
200 ///
201 /// ```rust
202 /// use std::io::{self, Write};
203 ///
204 /// let buffer = vec![1, 2, 3, 5, 8];
205 /// let num_bytes = io::sink().write(&buffer).unwrap();
206 /// assert_eq!(num_bytes, 5);
207 /// ```
208 #[must_use]
209 #[stable(feature = "rust1", since = "1.0.0")]
210 #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")]
211 pub const fn sink() -> Sink {
212     Sink
213 }
214
215 #[stable(feature = "rust1", since = "1.0.0")]
216 impl Write for Sink {
217     #[inline]
218     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
219         Ok(buf.len())
220     }
221
222     #[inline]
223     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
224         let total_len = bufs.iter().map(|b| b.len()).sum();
225         Ok(total_len)
226     }
227
228     #[inline]
229     fn is_write_vectored(&self) -> bool {
230         true
231     }
232
233     #[inline]
234     fn flush(&mut self) -> io::Result<()> {
235         Ok(())
236     }
237 }
238
239 #[stable(feature = "write_mt", since = "1.48.0")]
240 impl Write for &Sink {
241     #[inline]
242     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
243         Ok(buf.len())
244     }
245
246     #[inline]
247     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
248         let total_len = bufs.iter().map(|b| b.len()).sum();
249         Ok(total_len)
250     }
251
252     #[inline]
253     fn is_write_vectored(&self) -> bool {
254         true
255     }
256
257     #[inline]
258     fn flush(&mut self) -> io::Result<()> {
259         Ok(())
260     }
261 }
262
263 #[stable(feature = "std_debug", since = "1.16.0")]
264 impl fmt::Debug for Sink {
265     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266         f.debug_struct("Sink").finish_non_exhaustive()
267     }
268 }