use core::marker;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::io;
use musli::de::{Decode, Decoder};
use musli::en::{Encode, Encoder};
use musli::mode::Text;
use musli::Context;
use musli_utils::{FixedBytes, Writer};
use crate::de::JsonDecoder;
use crate::en::JsonEncoder;
use crate::error::Error;
use crate::parser::{Parser, SliceParser};
pub const DEFAULT: Encoding = Encoding::new();
#[inline]
pub fn encode<W, T>(writer: W, value: &T) -> Result<(), Error>
where
W: Writer,
T: ?Sized + Encode<Text>,
{
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<Text>,
{
DEFAULT.to_writer(writer, value)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, Error>
where
T: ?Sized + Encode<Text>,
{
DEFAULT.to_vec(value)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, Error>
where
T: ?Sized + Encode<Text>,
{
DEFAULT.to_string(value)
}
#[inline]
pub fn to_fixed_bytes<const N: usize, T>(value: &T) -> Result<FixedBytes<N>, Error>
where
T: ?Sized + Encode<Text>,
{
DEFAULT.to_fixed_bytes::<N, _>(value)
}
#[inline]
pub fn decode<'de, R, T>(reader: R) -> Result<T, Error>
where
R: Parser<'de>,
T: Decode<'de, Text>,
{
DEFAULT.decode(reader)
}
#[inline]
pub fn from_str<'de, T>(string: &'de str) -> Result<T, Error>
where
T: Decode<'de, Text>,
{
DEFAULT.from_str(string)
}
#[inline]
pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T, Error>
where
T: Decode<'de, Text>,
{
DEFAULT.from_slice(bytes)
}
pub struct Encoding<M = Text> {
_marker: marker::PhantomData<M>,
}
impl Encoding<Text> {
#[inline]
pub const fn new() -> Self {
Encoding {
_marker: marker::PhantomData,
}
}
}
impl<M> Encoding<M> {
pub const fn with_mode<T>(self) -> Encoding<T> {
Encoding {
_marker: marker::PhantomData,
}
}
#[inline]
pub fn encode_with<C, W, T>(self, cx: &C, writer: W, value: &T) -> Result<(), C::Error>
where
C: ?Sized + Context<Mode = M>,
W: Writer,
T: ?Sized + Encode<M>,
{
cx.clear();
JsonEncoder::new(cx, writer).encode(value)
}
#[cfg(feature = "alloc")]
#[inline]
pub fn to_string<T>(self, value: &T) -> Result<String, Error>
where
T: ?Sized + Encode<M>,
{
musli_utils::allocator::with(|alloc| {
let cx = musli_utils::context::Same::new(alloc);
self.to_string_with(&cx, value)
})
}
#[cfg(feature = "alloc")]
#[inline]
pub fn to_string_with<T, C>(self, cx: &C, value: &T) -> Result<String, C::Error>
where
C: ?Sized + Context<Mode = M>,
T: ?Sized + Encode<M>,
{
cx.clear();
let mut data = Vec::with_capacity(128);
JsonEncoder::new(cx, &mut data).encode(value)?;
Ok(unsafe { String::from_utf8_unchecked(data) })
}
#[inline]
pub fn decode<'de, P, T>(self, parser: P) -> Result<T, Error>
where
P: Parser<'de>,
T: Decode<'de, M>,
{
musli_utils::allocator::with(|alloc| {
let cx = musli_utils::context::Same::new(alloc);
self.decode_with(&cx, parser)
})
}
#[inline]
pub fn decode_with<'de, C, P, T>(self, cx: &C, parser: P) -> Result<T, C::Error>
where
C: ?Sized + Context<Mode = M>,
P: Parser<'de>,
T: Decode<'de, M>,
{
cx.clear();
JsonDecoder::new(cx, parser).decode()
}
#[inline]
pub fn from_str<'de, T>(self, string: &'de str) -> Result<T, Error>
where
T: Decode<'de, M>,
{
self.from_slice(string.as_bytes())
}
#[inline]
pub fn from_str_with<'de, C, T>(self, cx: &C, string: &'de str) -> Result<T, C::Error>
where
C: ?Sized + Context<Mode = M>,
T: Decode<'de, M>,
{
self.from_slice_with(cx, string.as_bytes())
}
#[inline]
pub fn from_slice<'de, T>(self, bytes: &'de [u8]) -> Result<T, Error>
where
T: Decode<'de, M>,
{
musli_utils::allocator::with(|alloc| {
let cx = musli_utils::context::Same::<_, M, _>::new(alloc);
self.from_slice_with(&cx, bytes)
})
}
#[inline]
pub fn from_slice_with<'de, C, T>(self, cx: &C, bytes: &'de [u8]) -> Result<T, C::Error>
where
C: ?Sized + Context<Mode = M>,
T: Decode<'de, M>,
{
cx.clear();
JsonDecoder::new(cx, SliceParser::new(bytes)).decode()
}
musli_utils::encode_with_extensions!(M);
}
impl<M> Clone for Encoding<M> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<M> Copy for Encoding<M> {}