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