Skip to main content

alloc/io/copy/
specialization.rs

1//! Provides specialization for `io::copy`.
2
3use super::CopyState;
4use crate::io::{BufReader, Read, Result, Take, Write};
5
6pub(super) trait SpecCopyInner {
7    /// The implementation of `io::copy` that can rely on platform specific specialization
8    /// provided by `libstd`.
9    fn copy<W: Write + ?Sized>(&mut self, writer: &mut W) -> Result<CopyState>;
10}
11
12impl<R: Read + ?Sized> SpecCopyInner for R {
13    default fn copy<W: Write + ?Sized>(&mut self, _writer: &mut W) -> Result<CopyState> {
14        Ok(CopyState::Fallback(0))
15    }
16}
17
18impl<R: SpecCopy> SpecCopyInner for R {
19    fn copy<W: Write + ?Sized>(&mut self, writer: &mut W) -> Result<CopyState> {
20        <R as SpecCopy>::copy(self, writer)
21    }
22}
23
24#[doc(hidden)]
25#[unstable(feature = "core_io_internals", reason = "exposed only for libstd", issue = "none")]
26#[rustc_specialization_trait]
27pub trait SpecCopy: Read {
28    /// Attempt to copy from this reader to the provided writer using a specialized
29    /// process.
30    ///
31    /// Note that this function does _not_ take `self` as a parameter, and instead
32    /// is passed a generic `Read` type `R`.
33    /// This allows the `Self` type to provide specialized implementations for
34    /// any combination of `Read` and `Write` types.
35    /// However, in practice `Self` and types wrapping `Self` will be passed as
36    /// the `reader` argument.
37    ///
38    /// As of time of writing, `&mut R`, `Take<R>`, and `BufReader<R>` will
39    /// forward to `R` for a specialized copy implementation.
40    fn copy<R: Read + ?Sized, W: Write + ?Sized>(
41        _reader: &mut R,
42        _writer: &mut W,
43    ) -> Result<CopyState>;
44}
45
46impl<T> SpecCopy for &mut T
47where
48    T: SpecCopy,
49{
50    fn copy<R: Read + ?Sized, W: Write + ?Sized>(
51        reader: &mut R,
52        writer: &mut W,
53    ) -> Result<CopyState> {
54        <T as SpecCopy>::copy(reader, writer)
55    }
56}
57
58impl<T: SpecCopy> SpecCopy for Take<T> {
59    fn copy<R: Read + ?Sized, W: Write + ?Sized>(
60        reader: &mut R,
61        writer: &mut W,
62    ) -> Result<CopyState> {
63        <T as SpecCopy>::copy(reader, writer)
64    }
65}
66
67impl<T: ?Sized + SpecCopy> SpecCopy for BufReader<T> {
68    fn copy<R: Read + ?Sized, W: Write + ?Sized>(
69        reader: &mut R,
70        writer: &mut W,
71    ) -> Result<CopyState> {
72        <T as SpecCopy>::copy(reader, writer)
73    }
74}