use core::marker;
#[cfg(feature = "alloc")]
use rust_alloc::string::String;
#[cfg(feature = "alloc")]
use rust_alloc::vec::Vec;
#[cfg(feature = "alloc")]
use crate::alloc::Global;
use crate::mode::Text;
use crate::{Context, Decode, Encode, IntoWriter, Writer};
use super::de::JsonDecoder;
use super::en::JsonEncoder;
#[cfg(feature = "alloc")]
use super::error::Error;
use super::parser::IntoParser;
use super::pretty_writer::{Pretty, PrettyWriter};
#[allow(unused)]
const DEFAULT: Encoding = Encoding::new();
#[allow(unused)]
const PRETTY: Encoding = Encoding::new().with_pretty(Pretty::new());
crate::macros::bare_encoding!(Text, DEFAULT, json, IntoParser, IntoWriter);
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, Error>
where
T: ?Sized + Encode<Text>,
{
DEFAULT.to_string(value)
}
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn to_string_pretty<T>(value: &T) -> Result<String, Error>
where
T: ?Sized + Encode<Text>,
{
PRETTY.to_string(value)
}
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn to_vec_pretty<T>(value: &T) -> Result<Vec<u8>, Error>
where
T: ?Sized + Encode<Text>,
{
PRETTY.to_vec(value)
}
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn to_slice_pretty<T>(out: &mut [u8], value: &T) -> Result<usize, Error>
where
T: ?Sized + Encode<Text>,
{
PRETTY.to_slice(out, value)
}
#[cfg(all(feature = "std", feature = "alloc"))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "alloc"))))]
#[inline]
pub fn to_writer_pretty<W, T>(writer: W, value: &T) -> Result<(), Error>
where
W: std::io::Write,
T: ?Sized + Encode<Text>,
{
PRETTY.to_writer(writer, value)
}
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn from_str<'de, T>(string: &'de str) -> Result<T, Error>
where
T: Decode<'de, Text, Global>,
{
DEFAULT.from_str(string)
}
pub struct Encoding<M = Text>
where
M: 'static,
{
pretty: Option<Pretty>,
_marker: marker::PhantomData<M>,
}
impl Default for Encoding<Text> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl Encoding<Text> {
#[inline]
pub const fn new() -> Self {
Encoding {
pretty: None,
_marker: marker::PhantomData,
}
}
}
impl<M> Encoding<M>
where
M: 'static,
{
pub const fn with_mode<T>(self) -> Encoding<T>
where
T: 'static,
{
Encoding {
pretty: self.pretty,
_marker: marker::PhantomData,
}
}
pub const fn with_pretty(self, pretty: Pretty) -> Encoding<M> {
Encoding {
pretty: Some(pretty),
..self
}
}
pub const fn with_compact(self) -> Encoding<M> {
Encoding {
pretty: None,
..self
}
}
#[inline]
fn encode_into<C, W, T>(self, cx: C, writer: W, value: &T) -> Result<(), C::Error>
where
C: Context,
W: Writer,
T: ?Sized + Encode<M>,
{
match self.pretty {
Some(pretty) => T::encode(
value,
JsonEncoder::new(cx, PrettyWriter::new(writer, pretty)),
),
None => T::encode(value, JsonEncoder::new(cx, writer)),
}
}
crate::macros::encoding_impls!(
custom,
M,
json,
JsonDecoder::<_, _, M>::new,
IntoParser::into_parser,
crate::json::parser::Parser,
IntoWriter::into_writer,
);
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn to_string<T>(self, value: &T) -> Result<String, Error>
where
T: ?Sized + Encode<M>,
{
let cx = crate::context::new().with_error();
self.to_string_with(&cx, value)
}
#[cfg(feature = "alloc")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[inline]
pub fn to_string_with<T, C>(self, cx: C, value: &T) -> Result<String, C::Error>
where
C: Context,
T: ?Sized + Encode<M>,
{
cx.clear();
let mut data = Vec::with_capacity(128);
self.encode_into(cx, &mut data, value)?;
Ok(unsafe { String::from_utf8_unchecked(data) })
}
}
impl<M> Clone for Encoding<M> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<M> Copy for Encoding<M> {}