Use macro to implement our traits for `std` types
We want to implement the traits for more types which would be tedious without a macro and it'd risk forgetting to forward some method since they may be speialized. This also adds previously-forgotten specializations. It also relaxes the implicit `Sized` bound on `BufReader` and `BufWriter` in Rust versions above 1.72.
This commit is contained in:
parent
505ecd8a2e
commit
5e30c9f190
|
@ -23,4 +23,4 @@ all-features = true
|
|||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "deny" }
|
||||
unexpected_cfgs = { level = "deny", check-cfg = ['cfg(rust_v_1_72)'] }
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
fn main() {
|
||||
let rustc = std::env::var_os("RUSTC");
|
||||
let rustc = rustc.as_ref().map(std::path::Path::new).unwrap_or_else(|| "rustc".as_ref());
|
||||
let output = std::process::Command::new(rustc)
|
||||
.arg("--version")
|
||||
.output()
|
||||
.unwrap_or_else(|error| panic!("failed to run `{:?} --version`: {:?}", rustc, error));
|
||||
assert!(output.status.success(), "{:?} -- version returned non-zero exit code", rustc);
|
||||
let stdout = String::from_utf8(output.stdout).expect("rustc produced non-UTF-8 output");
|
||||
let version_prefix = "rustc ";
|
||||
if !stdout.starts_with(version_prefix) {
|
||||
panic!("unexpected rustc output: {}", stdout);
|
||||
}
|
||||
|
||||
let version = &stdout[version_prefix.len()..];
|
||||
let end = version.find(&[' ', '-'] as &[_]).unwrap_or(version.len());
|
||||
let version = &version[..end];
|
||||
let mut version_components = version.split('.');
|
||||
let major = version_components.next().unwrap();
|
||||
assert_eq!(major, "1", "unexpected Rust major version");
|
||||
let minor = version_components
|
||||
.next()
|
||||
.unwrap_or("0")
|
||||
.parse::<u64>()
|
||||
.expect("invalid Rust minor version");
|
||||
|
||||
let msrv = std::env::var("CARGO_PKG_RUST_VERSION").unwrap();
|
||||
let mut msrv = msrv.split(".");
|
||||
let msrv_major = msrv.next().unwrap();
|
||||
assert_eq!(msrv_major, "1", "unexpected Rust major version");
|
||||
let msrv_minor = msrv.next().unwrap().parse::<u64>().unwrap();
|
||||
|
||||
// print cfg for all interesting versions less than or equal to minor
|
||||
for version in msrv_minor..=minor {
|
||||
println!("cargo:rustc-cfg=rust_v_1_{}", version);
|
||||
}
|
||||
}
|
|
@ -255,17 +255,73 @@ impl<T: super::Write> super::Write for ToStd<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: std::io::Read> super::Read for std::io::BufReader<R> {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> super::Result<usize> { Ok(std::io::Read::read(self, buf)?) }
|
||||
macro_rules! impl_our {
|
||||
(impl$(<$($gen:ident $(: $gent:path)?),*>)? Read for $std_type:ty $(where $($where:tt)*)?) => {
|
||||
impl$(<$($gen$(: $gent)?),*>)? super::Read for $std_type $(where $($where)*)? {
|
||||
#[inline]
|
||||
fn read(&mut self, buf: &mut [u8]) -> super::Result<usize> {
|
||||
std::io::Read::read(self, buf).map_err(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_exact(&mut self, buf: &mut [u8]) -> super::Result<()> {
|
||||
std::io::Read::read_exact(self, buf).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(impl$(<$($gen:ident $(: $gent:path)?),*>)? BufRead for $std_type:ty $(where $($where:tt)*)?) => {
|
||||
impl$(<$($gen$(: $gent)?),*>)? super::BufRead for $std_type $(where $($where)*)? {
|
||||
#[inline]
|
||||
fn fill_buf(&mut self) -> super::Result<&[u8]> {
|
||||
std::io::BufRead::fill_buf(self).map_err(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amount: usize) {
|
||||
std::io::BufRead::consume(self, amount)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(impl$(<$($gen:ident $(: $gent:path)?),*>)? Write for $std_type:ty $(where $($where:tt)*)?) => {
|
||||
impl$(<$($gen$(: $gent)?),*>)? super::Write for $std_type $(where $($where)*)? {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> super::Result<usize> {
|
||||
std::io::Write::write(self, buf).map_err(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> super::Result<()> {
|
||||
std::io::Write::flush(self).map_err(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> super::Result<()> {
|
||||
std::io::Write::write_all(self, buf).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<R: std::io::Read> super::BufRead for std::io::BufReader<R> {
|
||||
#[inline]
|
||||
fn fill_buf(&mut self) -> super::Result<&[u8]> { Ok(std::io::BufRead::fill_buf(self)?) }
|
||||
#[cfg(rust_v_1_72)]
|
||||
impl_our! {
|
||||
impl<R: std::io::Read> Read for std::io::BufReader<R> where R: ?Sized
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn consume(&mut self, amount: usize) { std::io::BufRead::consume(self, amount) }
|
||||
#[cfg(not(rust_v_1_72))]
|
||||
impl_our! {
|
||||
impl<R: std::io::Read> Read for std::io::BufReader<R>
|
||||
}
|
||||
|
||||
#[cfg(rust_v_1_72)]
|
||||
impl_our! {
|
||||
impl<R: std::io::Read> BufRead for std::io::BufReader<R> where R: ?Sized
|
||||
}
|
||||
|
||||
#[cfg(not(rust_v_1_72))]
|
||||
impl_our! {
|
||||
impl<R: std::io::Read> BufRead for std::io::BufReader<R>
|
||||
}
|
||||
|
||||
impl std::io::Write for super::Sink {
|
||||
|
@ -279,10 +335,12 @@ impl std::io::Write for super::Sink {
|
|||
fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
impl<W: std::io::Write> super::Write for std::io::BufWriter<W> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> super::Result<usize> { Ok(std::io::Write::write(self, buf)?) }
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> super::Result<()> { Ok(std::io::Write::flush(self)?) }
|
||||
#[cfg(rust_v_1_72)]
|
||||
impl_our! {
|
||||
impl<W: std::io::Write> Write for std::io::BufWriter<W> where W: ?Sized
|
||||
}
|
||||
|
||||
#[cfg(not(rust_v_1_72))]
|
||||
impl_our! {
|
||||
impl<W: std::io::Write> Write for std::io::BufWriter<W>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue