use core::marker;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::io;
use musli::de::Decode;
use musli::en::Encode;
use musli::mode::{DefaultMode, Mode};
use musli::Context;
use crate::de::WireDecoder;
use crate::en::WireEncoder;
use crate::error::Error;
use crate::fixed_bytes::FixedBytes;
use crate::int::{BigEndian, ByteOrder, Fixed, FixedUsize, LittleEndian, NetworkEndian, Variable};
use crate::integer_encoding::{WireIntegerEncoding, WireUsizeEncoding};
use crate::reader::{Reader, SliceReader};
use crate::writer::Writer;
pub const DEFAULT: Encoding = Encoding::new();
#[inline]
pub fn encode<W, T>(writer: W, value: &T) -> Result<(), Error>
where
W: Writer,
Error: From<W::Error>,
T: ?Sized + Encode<DefaultMode>,
{
DEFAULT.encode(writer, value)
}
#[cfg(feature = "std")]
#[inline]
pub fn to_writer<W, T>(writer: W, value: &T) -> Result<(), Error>
where
W: io::Write,
T: ?Sized + Encode<DefaultMode>,
{
DEFAULT.to_writer(writer, value)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, Error>
where
T: ?Sized + Encode<DefaultMode>,
{
DEFAULT.to_vec(value)
}
#[inline]
pub fn to_fixed_bytes<const N: usize, T>(value: &T) -> Result<FixedBytes<N>, Error>
where
T: ?Sized + Encode<DefaultMode>,
{
DEFAULT.to_fixed_bytes::<N, _>(value)
}
#[inline]
pub fn decode<'de, R, T>(reader: R) -> Result<T, Error>
where
R: Reader<'de>,
Error: From<R::Error>,
T: Decode<'de, DefaultMode>,
{
DEFAULT.decode(reader)
}
#[inline]
pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T, Error>
where
T: Decode<'de, DefaultMode>,
{
DEFAULT.from_slice(bytes)
}
pub struct Encoding<M = DefaultMode, I = Variable, L = Variable>
where
I: WireIntegerEncoding,
L: WireUsizeEncoding,
{
_marker: marker::PhantomData<(M, I, L)>,
}
impl Encoding<DefaultMode, Variable, Variable> {
pub const fn new() -> Self {
Encoding {
_marker: marker::PhantomData,
}
}
}
impl<M, I, L> Encoding<M, I, L>
where
M: Mode,
I: WireIntegerEncoding,
L: WireUsizeEncoding,
{
pub const fn with_mode<T>(self) -> Encoding<T, I, L>
where
T: Mode,
{
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_variable_integers(self) -> Encoding<M, Variable, L> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers(self) -> Encoding<M, Fixed, L> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_le(self) -> Encoding<M, Fixed<LittleEndian>, L> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_be(self) -> Encoding<M, Fixed<BigEndian>, L> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_ne(self) -> Encoding<M, Fixed<NetworkEndian>, L> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_integers_endian<E>(self) -> Encoding<M, Fixed<E>, L>
where
E: ByteOrder,
{
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_variable_lengths(self) -> Encoding<M, I, Variable> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_lengths(self) -> Encoding<M, I, FixedUsize<u32>> {
Encoding {
_marker: marker::PhantomData,
}
}
pub const fn with_fixed_lengths64(self) -> Encoding<M, I, FixedUsize<u64>> {
Encoding {
_marker: marker::PhantomData,
}
}
musli_common::encoding_impls! {
WireEncoder::<_, I, L>::new,
WireDecoder::<_, I, L>::new
}
musli_common::encoding_from_slice_impls! {
WireEncoder::<_, I, L>::new,
WireDecoder::<_, I, L>::new
}
}
impl<M, I, L> Clone for Encoding<M, I, L>
where
M: Mode,
I: WireIntegerEncoding,
L: WireUsizeEncoding,
{
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<M, I, L> Copy for Encoding<M, I, L>
where
M: Mode,
I: WireIntegerEncoding,
L: WireUsizeEncoding,
{
}