use std::borrow::Borrow;
use std::ops::{Deref, DerefMut};
use futures_lite::{AsyncWriteExt, io};
use crate::{Endianness, NativeEndian, Representable};
#[repr(transparent)]
pub struct AsyncWriteBytes<'a, W>(&'a mut W)
where
W: AsyncWriteExt + Unpin;
impl<W> Deref for AsyncWriteBytes<'_, W>
where
W: AsyncWriteExt + Unpin,
{
type Target = W;
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<W> DerefMut for AsyncWriteBytes<'_, W>
where
W: AsyncWriteExt + Unpin,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}
impl<'a, W> AsyncWriteBytes<'a, W>
where
W: AsyncWriteExt + Unpin,
{
#[must_use]
pub const fn new(writer: &'a mut W) -> Self {
Self(writer)
}
pub async fn write_representable<E, Re>(&mut self, value: Re) -> io::Result<()>
where
E: Endianness,
Re: Representable,
{
let buffer = E::from_representable(&value);
self.write_all(buffer.borrow()).await
}
#[inline]
pub async fn write_u8(&mut self, value: u8) -> io::Result<()> {
self.write_all(&[value]).await
}
#[inline]
pub async fn write_i8(&mut self, value: i8) -> io::Result<()> {
self.write_all(&[value.cast_unsigned()]).await
}
}
macro_rules! impl_async_write_bytes {
($(($num:ty, $write_name:ident, $write_name_ne:ident)),* $(,)?) => {
impl<W> AsyncWriteBytes<'_, W> where W: AsyncWriteExt + Unpin {
$(
/// # Errors
/// This method returns the same errors as [`AsyncWriteExt::write_all`].
#[inline]
pub async fn $write_name<E: Endianness>(&mut self, value: $num) -> io::Result<()> {
self.write_representable::<E, $num>(value).await
}
#[inline]
pub async fn $write_name_ne(&mut self, value: $num) -> io::Result<()> {
self.write_representable::<NativeEndian, $num>(value).await
}
)*
}
};
}
impl_async_write_bytes!(
(u16, write_u16, write_u16_ne),
(u32, write_u32, write_u32_ne),
(u64, write_u64, write_u64_ne),
(u128, write_u128, write_u128_ne),
(i16, write_i16, write_i16_ne),
(i32, write_i32, write_i32_ne),
(i64, write_i64, write_i64_ne),
(i128, write_i128, write_i128_ne),
(f32, write_f32, write_f32_ne),
(f64, write_f64, write_f64_ne),
);
impl<'a, W> From<&'a mut W> for AsyncWriteBytes<'a, W>
where
W: AsyncWriteExt + Unpin,
{
fn from(writer: &'a mut W) -> Self {
Self::new(writer)
}
}