futures_lite_byteorder/
lib.rs

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 {}