use core::marker;
#[cfg(feature = "std")]
use std::io;
use crate::de::WireDecoder;
use crate::en::WireEncoder;
use crate::integer_encoding::{Fixed, FixedLength, IntegerEncoding, UsizeEncoding, Variable};
use musli::Decode;
use musli::Encode;
use musli_binary_common::fixed_bytes::{FixedBytes, FixedBytesWriterError};
use musli_binary_common::int::{BigEndian, LittleEndian, NetworkEndian};
use musli_binary_common::reader::Reader;
#[cfg(feature = "std")]
use musli_binary_common::writer::VecWriterError;
use musli_binary_common::writer::Writer;
const DEFAULT: WireEncoding<Variable, Variable> = WireEncoding::new();
pub fn encode<W, T>(writer: W, value: &T) -> Result<(), W::Error>
where
W: Writer,
T: ?Sized + Encode,
{
DEFAULT.encode(writer, value)
}
#[cfg(feature = "std")]
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<(), io::Error>
where
W: io::Write,
T: ?Sized + Encode,
{
DEFAULT.to_writer(writer, value)
}
#[cfg(feature = "std")]
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, VecWriterError>
where
T: ?Sized + Encode,
{
DEFAULT.to_vec(value)
}
pub fn to_fixed_bytes<const N: usize, T>(value: &T) -> Result<FixedBytes<N>, FixedBytesWriterError>
where
T: ?Sized + Encode,
{
DEFAULT.to_fixed_bytes::<N, _>(value)
}
pub fn decode<'de, R, T>(reader: R) -> Result<T, R::Error>
where
R: Reader<'de>,
T: Decode<'de>,
{
DEFAULT.decode(reader)
}
#[derive(Clone, Copy)]
pub struct WireEncoding<I, L>
where
I: IntegerEncoding,
L: UsizeEncoding,
{
_marker: marker::PhantomData<(I, L)>,
}
impl WireEncoding<Variable, Variable> {
pub const fn new() -> Self {
WireEncoding {
_marker: marker::PhantomData,
}
}
}
impl<I, L> WireEncoding<I, L>
where
I: IntegerEncoding,
L: UsizeEncoding,
{
pub const fn with_variable_integers(self) -> WireEncoding<Variable, L> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers(self) -> WireEncoding<Fixed, L> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_le(self) -> WireEncoding<Fixed<LittleEndian>, L> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_be(self) -> WireEncoding<Fixed<BigEndian>, L> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_ne(self) -> WireEncoding<Fixed<NetworkEndian>, L> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_variable_lengths(self) -> WireEncoding<I, Variable> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_lengths(self) -> WireEncoding<I, FixedLength<u32>> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_lengths64(self) -> WireEncoding<I, FixedLength<u64>> {
WireEncoding {
_marker: marker::PhantomData,
}
}
pub fn encode<W, T>(self, mut writer: W, value: &T) -> Result<(), W::Error>
where
W: Writer,
T: ?Sized + Encode,
{
T::encode(value, WireEncoder::<_, I, L>::new(&mut writer))
}
#[cfg(feature = "std")]
pub fn to_writer<W, T>(self, write: W, value: &T) -> Result<(), io::Error>
where
W: io::Write,
T: ?Sized + Encode,
{
let mut writer = musli_binary_common::io::wrap(write);
T::encode(value, WireEncoder::<_, I, L>::new(&mut writer))
}
#[cfg(feature = "std")]
pub fn to_vec<T>(self, value: &T) -> Result<Vec<u8>, VecWriterError>
where
T: ?Sized + Encode,
{
let mut data = Vec::new();
T::encode(value, WireEncoder::<_, I, L>::new(&mut data))?;
Ok(data)
}
pub fn to_fixed_bytes<const N: usize, T>(
self,
value: &T,
) -> Result<FixedBytes<N>, FixedBytesWriterError>
where
T: ?Sized + Encode,
{
let mut bytes = FixedBytes::new();
T::encode(value, WireEncoder::<_, I, L>::new(&mut bytes))?;
Ok(bytes)
}
pub fn decode<'de, R, T>(self, reader: R) -> Result<T, R::Error>
where
R: Reader<'de>,
T: Decode<'de>,
{
let mut reader = reader.with_position();
T::decode(WireDecoder::<_, I, L>::new(&mut reader))
}
}