1use crate::io::{self, ErrorKind, IoSlice, Result, Seek, SeekFrom, SizeHint, Write};
2use crate::{cmp, fmt};
3
4#[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#[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#[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#[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#[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#[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#[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 #[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 #[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 #[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#[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 #[stable(feature = "rust1", since = "1.0.0")]
517 pub fn limit(&self) -> u64 {
518 self.limit
519 }
520
521 #[unstable(feature = "seek_io_take_position", issue = "97227")]
523 #[inline]
524 pub fn position(&self) -> u64 {
525 self.len - self.limit
526 }
527
528 #[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 #[stable(feature = "io_take_into_inner", since = "1.15.0")]
578 pub fn into_inner(self) -> T {
579 self.inner
580 }
581
582 #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
607 pub fn get_ref(&self) -> &T {
608 &self.inner
609 }
610
611 #[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}