esexpr_binary/
io.rs

1use alloc::vec::Vec;
2use core::convert::Infallible;
3
4/// IO `Read` type with an error parameter
5pub trait Read<Error> {
6	/// Read bytes into the buffer
7	///
8	/// # Errors
9	/// Returns an error if an IO error occurs.
10	fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>;
11}
12
13impl<'a> Read<Infallible> for &'a [u8] {
14	fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
15		let len = core::cmp::min(self.len(), buf.len());
16		buf[..len].copy_from_slice(&self[..len]);
17		*self = &self[len..];
18		Ok(len)
19	}
20}
21
22#[cfg(feature = "std")]
23impl<R: std::io::Read> Read<std::io::Error> for R {
24	fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
25		loop {
26			return match self.read(buf) {
27				Ok(n) => Ok(n),
28				Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
29				Err(e) => Err(e),
30			};
31		}
32	}
33}
34
35/// IO `Write` type with an error parameter
36pub trait Write<Error> {
37	/// Write bytes from the buffer
38	///
39	/// # Errors
40	/// Returns an error if an IO error occurs.
41	fn write(&mut self, buf: &[u8]) -> Result<(), Error>;
42}
43
44impl Write<Infallible> for Vec<u8> {
45	fn write(&mut self, buf: &[u8]) -> Result<(), Infallible> {
46		self.extend_from_slice(buf);
47		Ok(())
48	}
49}
50
51#[cfg(feature = "std")]
52impl<W: std::io::Write> Write<std::io::Error> for W {
53	fn write(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
54		self.write_all(buf)
55	}
56}
57
58/// IO `AsyncRead` type with an error parameter
59#[allow(async_fn_in_trait, reason = "No additional traits to add")]
60pub trait AsyncRead<Error> {
61	/// Read bytes into the buffer
62	///
63	/// # Errors
64	/// Returns an error if an IO error occurs.
65	async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>;
66}
67
68impl<'a> AsyncRead<Infallible> for &'a [u8] {
69	async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
70		let len = core::cmp::min(self.len(), buf.len());
71		buf.copy_from_slice(&self[..len]);
72		*self = &self[len..];
73		Ok(len)
74	}
75}
76
77#[cfg(feature = "std")]
78impl<R: futures::io::AsyncRead + std::marker::Unpin> AsyncRead<std::io::Error> for R {
79	async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
80		<R as futures::io::AsyncReadExt>::read(self, buf).await
81	}
82}
83
84/// IO `AsyncWrite` type with an error parameter
85#[allow(async_fn_in_trait, reason = "No additional traits to add")]
86pub trait AsyncWrite<Error> {
87	/// Write bytes from the buffer
88	///
89	/// # Errors
90	/// Returns an error if an IO error occurs.
91	async fn write(&mut self, buf: &[u8]) -> Result<(), Error>;
92}
93
94impl AsyncWrite<Infallible> for Vec<u8> {
95	async fn write(&mut self, buf: &[u8]) -> Result<(), Infallible> {
96		self.extend_from_slice(buf);
97		Ok(())
98	}
99}
100
101#[cfg(feature = "std")]
102impl<W: futures::io::AsyncWrite + std::marker::Unpin> AsyncWrite<std::io::Error> for W {
103	async fn write(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
104		<W as futures::io::AsyncWriteExt>::write_all(self, buf).await
105	}
106}
107
108struct Sink;
109
110impl Write<Infallible> for Sink {
111	fn write(&mut self, _buf: &[u8]) -> Result<(), Infallible> {
112		Ok(())
113	}
114}
115
116impl AsyncWrite<Infallible> for Sink {
117	async fn write(&mut self, _buf: &[u8]) -> Result<(), Infallible> {
118		Ok(())
119	}
120}
121
122/// Returns a sink that discards all data written to it.
123#[must_use]
124pub fn sink() -> impl Write<Infallible> + AsyncWrite<Infallible> {
125	Sink
126}