|
| 1 | +//! Adapters to/from `std::io` traits. |
| 2 | +//! |
| 3 | +//! To interoperate with `std::io`, wrap a type in one of these |
| 4 | +//! adapters. |
| 5 | +//! |
| 6 | +//! There's no separate adapters for Read/ReadBuf/Write traits. Instead, a single |
| 7 | +//! adapter implements the right traits based on what the inner type implements. |
| 8 | +//! This allows adapting a `Read+Write`, for example. |
| 9 | +
|
| 10 | +use crate::SeekFrom; |
| 11 | + |
| 12 | +/// Adapter from `std::io` traits. |
| 13 | +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] |
| 14 | +#[derive(Clone)] |
| 15 | +pub struct FromStd<T: ?Sized> { |
| 16 | + inner: T, |
| 17 | +} |
| 18 | + |
| 19 | +impl<T> FromStd<T> { |
| 20 | + /// Create a new adapter. |
| 21 | + pub fn new(inner: T) -> Self { |
| 22 | + Self { inner } |
| 23 | + } |
| 24 | + |
| 25 | + /// Consume the adapter, returning the inner object. |
| 26 | + pub fn into_inner(self) -> T { |
| 27 | + self.inner |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +impl<T: ?Sized> FromStd<T> { |
| 32 | + /// Borrow the inner object. |
| 33 | + pub fn inner(&self) -> &T { |
| 34 | + &self.inner |
| 35 | + } |
| 36 | + |
| 37 | + /// Mutably borrow the inner object. |
| 38 | + pub fn inner_mut(&mut self) -> &mut T { |
| 39 | + &mut self.inner |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +impl<T: ?Sized> crate::Io for FromStd<T> { |
| 44 | + type Error = std::io::Error; |
| 45 | +} |
| 46 | + |
| 47 | +impl<T: std::io::Read + ?Sized> crate::Read for FromStd<T> { |
| 48 | + fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> { |
| 49 | + self.inner.read(buf) |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +impl<T: std::io::BufRead + ?Sized> crate::BufRead for FromStd<T> { |
| 54 | + fn fill_buf(&mut self) -> Result<&[u8], Self::Error> { |
| 55 | + self.inner.fill_buf() |
| 56 | + } |
| 57 | + |
| 58 | + fn consume(&mut self, amt: usize) { |
| 59 | + self.inner.consume(amt) |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +impl<T: std::io::Write + ?Sized> crate::Write for FromStd<T> { |
| 64 | + fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> { |
| 65 | + self.inner.write(buf) |
| 66 | + } |
| 67 | + fn flush(&mut self) -> Result<(), Self::Error> { |
| 68 | + self.inner.flush() |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +impl<T: std::io::Seek + ?Sized> crate::Seek for FromStd<T> { |
| 73 | + fn seek(&mut self, pos: crate::SeekFrom) -> Result<u64, Self::Error> { |
| 74 | + self.inner.seek(pos.into()) |
| 75 | + } |
| 76 | +} |
| 77 | + |
| 78 | +/// Adapter to `std::io` traits. |
| 79 | +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] |
| 80 | +pub struct ToStd<T: ?Sized> { |
| 81 | + inner: T, |
| 82 | +} |
| 83 | + |
| 84 | +impl<T> ToStd<T> { |
| 85 | + /// Create a new adapter. |
| 86 | + pub fn new(inner: T) -> Self { |
| 87 | + Self { inner } |
| 88 | + } |
| 89 | + |
| 90 | + /// Consume the adapter, returning the inner object. |
| 91 | + pub fn into_inner(self) -> T { |
| 92 | + self.inner |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +impl<T: ?Sized> ToStd<T> { |
| 97 | + /// Borrow the inner object. |
| 98 | + pub fn inner(&self) -> &T { |
| 99 | + &self.inner |
| 100 | + } |
| 101 | + |
| 102 | + /// Mutably borrow the inner object. |
| 103 | + pub fn inner_mut(&mut self) -> &mut T { |
| 104 | + &mut self.inner |
| 105 | + } |
| 106 | +} |
| 107 | + |
| 108 | +impl<T: crate::Read + ?Sized> std::io::Read for ToStd<T> { |
| 109 | + fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> { |
| 110 | + self.inner.read(buf).map_err(to_io_error) |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +impl<T: crate::Write + ?Sized> std::io::Write for ToStd<T> { |
| 115 | + fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> { |
| 116 | + self.inner.write(buf).map_err(to_io_error) |
| 117 | + } |
| 118 | + fn flush(&mut self) -> Result<(), std::io::Error> { |
| 119 | + self.inner.flush().map_err(to_io_error) |
| 120 | + } |
| 121 | +} |
| 122 | + |
| 123 | +impl<T: crate::Seek + ?Sized> std::io::Seek for ToStd<T> { |
| 124 | + fn seek(&mut self, pos: std::io::SeekFrom) -> Result<u64, std::io::Error> { |
| 125 | + self.inner.seek(pos.into()).map_err(to_io_error) |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +fn to_io_error<T: core::fmt::Debug>(err: T) -> std::io::Error { |
| 130 | + let kind = std::io::ErrorKind::Other; |
| 131 | + std::io::Error::new(kind, format!("{:?}", err)) |
| 132 | +} |
| 133 | + |
| 134 | +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] |
| 135 | +impl crate::Error for std::io::Error { |
| 136 | + fn kind(&self) -> crate::ErrorKind { |
| 137 | + crate::ErrorKind::Other |
| 138 | + } |
| 139 | +} |
| 140 | + |
| 141 | +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] |
| 142 | +impl From<SeekFrom> for std::io::SeekFrom { |
| 143 | + fn from(pos: SeekFrom) -> Self { |
| 144 | + match pos { |
| 145 | + SeekFrom::Start(n) => std::io::SeekFrom::Start(n), |
| 146 | + SeekFrom::End(n) => std::io::SeekFrom::End(n), |
| 147 | + SeekFrom::Current(n) => std::io::SeekFrom::Current(n), |
| 148 | + } |
| 149 | + } |
| 150 | +} |
| 151 | + |
| 152 | +#[cfg_attr(docsrs, doc(cfg(feature = "std")))] |
| 153 | +impl From<std::io::SeekFrom> for SeekFrom { |
| 154 | + fn from(pos: std::io::SeekFrom) -> SeekFrom { |
| 155 | + match pos { |
| 156 | + std::io::SeekFrom::Start(n) => SeekFrom::Start(n), |
| 157 | + std::io::SeekFrom::End(n) => SeekFrom::End(n), |
| 158 | + std::io::SeekFrom::Current(n) => SeekFrom::Current(n), |
| 159 | + } |
| 160 | + } |
| 161 | +} |
0 commit comments