mod impls;
use crate::{
io::{Seek, Write},
BinResult, Endian,
};
pub trait BinWrite {
type Args: Clone;
#[inline]
fn write<W: Write + Seek>(&self, writer: &mut W) -> BinResult<()>
where
Self: crate::meta::WriteEndian,
Self::Args: Default,
{
self.write_args(writer, Self::Args::default())
}
#[inline]
fn write_be<W: Write + Seek>(&self, writer: &mut W) -> BinResult<()>
where
Self::Args: Default,
{
self.write_be_args(writer, Self::Args::default())
}
#[inline]
fn write_le<W: Write + Seek>(&self, writer: &mut W) -> BinResult<()>
where
Self::Args: Default,
{
self.write_le_args(writer, Self::Args::default())
}
#[inline]
fn write_args<W: Write + Seek>(&self, writer: &mut W, args: Self::Args) -> BinResult<()>
where
Self: crate::meta::WriteEndian,
{
self.write_options(writer, &WriteOptions::new(Endian::Little), args)
}
#[inline]
fn write_be_args<W: Write + Seek>(&self, writer: &mut W, args: Self::Args) -> BinResult<()> {
self.write_options(writer, &WriteOptions::new(Endian::Big), args)
}
#[inline]
fn write_le_args<W: Write + Seek>(&self, writer: &mut W, args: Self::Args) -> BinResult<()> {
self.write_options(writer, &WriteOptions::new(Endian::Little), args)
}
fn write_options<W: Write + Seek>(
&self,
writer: &mut W,
options: &WriteOptions,
args: Self::Args,
) -> BinResult<()>;
}
#[derive(Clone, Copy)]
pub struct WriteOptions {
endian: Endian,
}
impl WriteOptions {
#[must_use]
pub fn new(endian: Endian) -> Self {
Self { endian }
}
#[must_use]
pub fn endian(&self) -> Endian {
self.endian
}
#[must_use]
#[allow(clippy::unused_self)]
pub fn with_endian(self, endian: Endian) -> Self {
Self { endian }
}
}
pub trait BinWriterExt: Write + Seek + Sized {
fn write_type<T: BinWrite>(&mut self, value: &T, endian: Endian) -> BinResult<()>
where
T::Args: Default,
{
self.write_type_args(value, endian, T::Args::default())
}
fn write_be<T: BinWrite>(&mut self, value: &T) -> BinResult<()>
where
T::Args: Default,
{
self.write_type(value, Endian::Big)
}
fn write_le<T: BinWrite>(&mut self, value: &T) -> BinResult<()>
where
T::Args: Default,
{
self.write_type(value, Endian::Little)
}
fn write_ne<T: BinWrite>(&mut self, value: &T) -> BinResult<()>
where
T::Args: Default,
{
self.write_type(value, Endian::NATIVE)
}
fn write_type_args<T: BinWrite>(
&mut self,
value: &T,
endian: Endian,
args: T::Args,
) -> BinResult<()> {
let options = WriteOptions::new(endian);
T::write_options(value, self, &options, args)?;
Ok(())
}
fn write_be_args<T: BinWrite>(&mut self, value: &T, args: T::Args) -> BinResult<()> {
self.write_type_args(value, Endian::Big, args)
}
fn write_le_args<T: BinWrite>(&mut self, value: &T, args: T::Args) -> BinResult<()> {
self.write_type_args(value, Endian::Little, args)
}
fn write_ne_args<T: BinWrite>(&mut self, value: &T, args: T::Args) -> BinResult<()> {
self.write_type_args(value, Endian::NATIVE, args)
}
}
impl<W: Write + Seek + Sized> BinWriterExt for W {}