[IO] Move to custom `Write` trait mirroring `std::io::Write`
In order to move towards our own I/O traits in the `rust-bitcoin` ecosystem, we have to slowly replace our use of the `std` and `core2` traits. Here we take the first real step, replacing `{std,core2}::io::Write` withour own `bitcoin_io::io::Write`. We provide a blanket impl for our trait for all `std::io::Write`, if the `std` feature is enabled, allowing users who use their own streams or `std` streams to call `rust-bitcoin` methods directly.
This commit is contained in:
parent
5f2395ce56
commit
ac678bb435
|
@ -36,10 +36,63 @@ pub mod io {
|
|||
compile_error!("At least one of std or core2 must be enabled");
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::io::{Read, Write, sink, Cursor, Take, Error, ErrorKind, Result};
|
||||
pub use std::io::{Read, sink, Cursor, Take, Error, ErrorKind, Result};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub use core2::io::{Read, Write, Cursor, Take, Error, ErrorKind, Result};
|
||||
pub use core2::io::{Read, Cursor, Take, Error, ErrorKind, Result};
|
||||
|
||||
/// A generic trait describing an output stream. See [`std::io::Write`] for more info.
|
||||
pub trait Write {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize>;
|
||||
fn flush(&mut self) -> Result<()>;
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
|
||||
while !buf.is_empty() {
|
||||
match self.write(buf) {
|
||||
Ok(0) => return Err(Error::new(ErrorKind::UnexpectedEof, "")),
|
||||
Ok(len) => buf = &buf[len..],
|
||||
Err(e) if e.kind() == ErrorKind::Interrupted => {}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<W: std::io::Write> Write for W {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
<W as std::io::Write>::write(self, buf)
|
||||
}
|
||||
#[inline]
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
<W as std::io::Write>::flush(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||
impl Write for alloc::vec::Vec<u8> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
self.extend_from_slice(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
#[inline]
|
||||
fn flush(&mut self) -> Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl<'a> Write for &'a mut [u8] {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
let cnt = core::cmp::min(self.len(), buf.len());
|
||||
self[..cnt].copy_from_slice(&buf[..cnt]);
|
||||
*self = &mut core::mem::take(self)[cnt..];
|
||||
Ok(cnt)
|
||||
}
|
||||
#[inline]
|
||||
fn flush(&mut self) -> Result<()> { Ok(()) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue