1use std::{
2 future::Future,
3 io::ErrorKind,
4 marker::PhantomData,
5 mem,
6 pin::Pin,
7 task::{Context, Poll},
8};
9
10use byteorder::ByteOrder;
11use futures_lite::{io, ready, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
12
13macro_rules! write_future_8 {
14 ($future: ident, $ty: ty) => {
15 pub struct $future<'a, W: Unpin + ?Sized> {
16 writer: &'a mut W,
17 buf: [u8; 1],
18 }
19
20 impl<W: AsyncWrite + Unpin + ?Sized> Future for $future<'_, W> {
21 type Output = io::Result<()>;
22
23 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
24 let Self { writer, buf } = &mut *self;
25
26 let n = ready!(Pin::new(&mut **writer).poll_write(cx, buf))?;
27
28 if n == 0 {
29 return Poll::Ready(Err(ErrorKind::WriteZero.into()))
30 }
31
32 Poll::Ready(Ok(()))
33 }
34 }
35 };
36}
37
38macro_rules! write_future {
39 ($future: ident, $ty: ty) => {
40 pub struct $future<'a, W: Unpin + ?Sized> {
41 writer: &'a mut W,
42 buf: [u8; mem::size_of::<$ty>()],
43 n: usize,
44 }
45
46 impl<W: AsyncWrite + Unpin + ?Sized> Future for $future<'_, W> {
47 type Output = io::Result<()>;
48
49 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
50 let Self { writer, buf, n } = &mut *self;
51
52 while *n < buf.len() {
53 *n = ready!(Pin::new(&mut **writer).poll_write(cx, &buf[*n..]))?;
54
55 if *n == 0 {
56 return Poll::Ready(Err(ErrorKind::WriteZero.into()))
57 }
58 }
59
60 Poll::Ready(Ok(()))
61 }
62 }
63 };
64}
65
66macro_rules! write_impl_8 {
67 ($future: ident, $name: ident, $ty: ty) => {
68 fn $name(&mut self, value: $ty) -> $future<'_, Self>
69 where
70 Self: Unpin,
71 {
72 $future {
73 writer: self,
74 buf: [value as u8],
75 }
76 }
77 };
78}
79
80macro_rules! write_impl {
81 ($future: ident, $name: ident, $ty: ty) => {
82 fn $name<T: ByteOrder>(&mut self, value: $ty) -> $future<'_, Self>
83 where
84 Self: Unpin,
85 {
86 let mut future = $future {
87 writer: self,
88 buf: [0; mem::size_of::<$ty>()],
89 n: 0,
90 };
91 T::$name(&mut future.buf, value);
92
93 future
94 }
95 };
96}
97
98write_future_8!(WriteU8Future, u8);
99write_future_8!(WriteI8Future, i8);
100
101write_future!(WriteU16Future, u16);
102write_future!(WriteI16Future, i16);
103write_future!(WriteU32Future, u32);
104write_future!(WriteI32Future, i32);
105write_future!(WriteU64Future, u64);
106write_future!(WriteI64Future, i64);
107
108pub trait AsyncByteOrderWrite: AsyncWriteExt {
109 write_impl_8!(WriteU8Future, write_u8, u8);
110 write_impl_8!(WriteI8Future, write_i8, i8);
111
112 write_impl!(WriteU16Future, write_u16, u16);
113 write_impl!(WriteI16Future, write_i16, i16);
114 write_impl!(WriteU32Future, write_u32, u32);
115 write_impl!(WriteI32Future, write_i32, i32);
116 write_impl!(WriteU64Future, write_u64, u64);
117 write_impl!(WriteI64Future, write_i64, i64);
118}
119
120impl<W: AsyncWriteExt> AsyncByteOrderWrite for W {}
121
122macro_rules! read_future_8 {
123 ($future: ident, $ty: ty) => {
124 pub struct $future<'a, R: Unpin + ?Sized> {
125 reader: &'a mut R,
126 buf: [u8; 1],
127 }
128
129 impl<R: AsyncRead + Unpin + ?Sized> Future for $future<'_, R> {
130 type Output = io::Result<$ty>;
131
132 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
133 let Self { reader, buf } = &mut *self;
134
135 let n = ready!(Pin::new(&mut *reader).poll_read(cx, buf))?;
136
137 if n == 0 {
138 return Poll::Ready(Err(ErrorKind::UnexpectedEof.into()))
139 }
140
141 Poll::Ready(Ok((buf[0] as $ty)))
142 }
143 }
144 };
145}
146
147macro_rules! read_future {
148 ($future: ident, $name: ident, $ty: ty) => {
149 pub struct $future<'a, R: Unpin + ?Sized, T: ByteOrder> {
150 reader: &'a mut R,
151 buf: [u8; mem::size_of::<$ty>()],
152 n: usize,
153 phantom: PhantomData<&'a T>,
154 }
155
156 impl<R: AsyncRead + Unpin + ?Sized, T: ByteOrder> Future for $future<'_, R, T> {
157 type Output = io::Result<$ty>;
158
159 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
160 let Self { reader, buf, n, .. } = &mut *self;
161
162 while *n < buf.len() {
163 *n = ready!(Pin::new(&mut **reader).poll_read(cx, &mut buf[*n..]))?;
164
165 if *n == 0 {
166 return Poll::Ready(Err(ErrorKind::UnexpectedEof.into()))
167 }
168 }
169
170 Poll::Ready(Ok(T::$name(buf)))
171 }
172 }
173 };
174}
175
176macro_rules! read_impl_8 {
177 ($future: ident, $name: ident, $ty: ty) => {
178 fn $name(&mut self) -> $future<'_, Self>
179 where
180 Self: Unpin,
181 {
182 $future {
183 reader: self,
184 buf: Default::default(),
185 }
186 }
187 };
188}
189
190macro_rules! read_impl {
191 ($future: ident, $name: ident, $ty: ty) => {
192 fn $name<T: ByteOrder>(&mut self) -> $future<'_, Self, T>
193 where
194 Self: Unpin,
195 {
196 $future {
197 reader: self,
198 buf: Default::default(),
199 n: 0,
200 phantom: PhantomData,
201 }
202 }
203 };
204}
205
206read_future_8!(ReadU8Future, u8);
207read_future_8!(ReadI8Future, i8);
208
209read_future!(ReadU16Future, read_u16, u16);
210read_future!(ReadI16Future, read_i16, i16);
211read_future!(ReadU32Future, read_u32, u32);
212read_future!(ReadI32Future, read_i32, i32);
213read_future!(ReadU64Future, read_u64, u64);
214read_future!(ReadI64Future, read_i64, i64);
215
216pub trait AsyncByteOrderRead: AsyncReadExt {
217 read_impl_8!(ReadU8Future, read_u8, u8);
218 read_impl_8!(ReadI8Future, read_i8, i8);
219
220 read_impl!(ReadU16Future, read_u16, u16);
221 read_impl!(ReadI16Future, read_i16, i16);
222 read_impl!(ReadU32Future, read_u32, u32);
223 read_impl!(ReadI32Future, read_i32, i32);
224 read_impl!(ReadU64Future, read_u64, u64);
225 read_impl!(ReadI64Future, read_i64, i64);
226}
227
228impl<R: AsyncReadExt> AsyncByteOrderRead for R {}