1use core::marker;
5
6#[cfg(feature = "alloc")]
7use alloc::string::String;
8#[cfg(feature = "alloc")]
9use alloc::vec::Vec;
10
11#[cfg(feature = "std")]
12use std::io;
13
14use musli::de::{Decode, Decoder};
15use musli::en::{Encode, Encoder};
16use musli::mode::Text;
17use musli::Context;
18use musli_utils::{FixedBytes, Writer};
19
20use crate::de::JsonDecoder;
21use crate::en::JsonEncoder;
22use crate::error::Error;
23use crate::parser::{Parser, SliceParser};
24
25pub const DEFAULT: Encoding = Encoding::new();
27
28#[inline]
31pub fn encode<W, T>(writer: W, value: &T) -> Result<(), Error>
32where
33 W: Writer,
34 T: ?Sized + Encode<Text>,
35{
36 DEFAULT.encode(writer, value)
37}
38
39#[cfg(feature = "std")]
42#[inline]
43pub fn to_writer<W, T>(writer: W, value: &T) -> Result<(), Error>
44where
45 W: io::Write,
46 T: ?Sized + Encode<Text>,
47{
48 DEFAULT.to_writer(writer, value)
49}
50
51#[cfg(feature = "alloc")]
53#[inline]
54pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, Error>
55where
56 T: ?Sized + Encode<Text>,
57{
58 DEFAULT.to_vec(value)
59}
60
61#[cfg(feature = "alloc")]
63#[inline]
64pub fn to_string<T>(value: &T) -> Result<String, Error>
65where
66 T: ?Sized + Encode<Text>,
67{
68 DEFAULT.to_string(value)
69}
70
71#[inline]
74pub fn to_fixed_bytes<const N: usize, T>(value: &T) -> Result<FixedBytes<N>, Error>
75where
76 T: ?Sized + Encode<Text>,
77{
78 DEFAULT.to_fixed_bytes::<N, _>(value)
79}
80
81#[inline]
84pub fn decode<'de, R, T>(reader: R) -> Result<T, Error>
85where
86 R: Parser<'de>,
87 T: Decode<'de, Text>,
88{
89 DEFAULT.decode(reader)
90}
91
92#[inline]
95pub fn from_str<'de, T>(string: &'de str) -> Result<T, Error>
96where
97 T: Decode<'de, Text>,
98{
99 DEFAULT.from_str(string)
100}
101
102#[inline]
105pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T, Error>
106where
107 T: Decode<'de, Text>,
108{
109 DEFAULT.from_slice(bytes)
110}
111
112pub struct Encoding<M = Text> {
114 _marker: marker::PhantomData<M>,
115}
116
117impl Encoding<Text> {
118 #[inline]
153 pub const fn new() -> Self {
154 Encoding {
155 _marker: marker::PhantomData,
156 }
157 }
158}
159
160impl<M> Encoding<M> {
161 pub const fn with_mode<T>(self) -> Encoding<T> {
173 Encoding {
174 _marker: marker::PhantomData,
175 }
176 }
177
178 #[inline]
184 pub fn encode_with<C, W, T>(self, cx: &C, writer: W, value: &T) -> Result<(), C::Error>
185 where
186 C: ?Sized + Context<Mode = M>,
187 W: Writer,
188 T: ?Sized + Encode<M>,
189 {
190 cx.clear();
191 JsonEncoder::new(cx, writer).encode(value)
192 }
193
194 #[cfg(feature = "alloc")]
196 #[inline]
197 pub fn to_string<T>(self, value: &T) -> Result<String, Error>
198 where
199 T: ?Sized + Encode<M>,
200 {
201 musli_utils::allocator::with(|alloc| {
202 let cx = musli_utils::context::Same::new(alloc);
203 self.to_string_with(&cx, value)
204 })
205 }
206
207 #[cfg(feature = "alloc")]
212 #[inline]
213 pub fn to_string_with<T, C>(self, cx: &C, value: &T) -> Result<String, C::Error>
214 where
215 C: ?Sized + Context<Mode = M>,
216 T: ?Sized + Encode<M>,
217 {
218 cx.clear();
219 let mut data = Vec::with_capacity(128);
220 JsonEncoder::new(cx, &mut data).encode(value)?;
221 Ok(unsafe { String::from_utf8_unchecked(data) })
223 }
224
225 #[inline]
228 pub fn decode<'de, P, T>(self, parser: P) -> Result<T, Error>
229 where
230 P: Parser<'de>,
231 T: Decode<'de, M>,
232 {
233 musli_utils::allocator::with(|alloc| {
234 let cx = musli_utils::context::Same::new(alloc);
235 self.decode_with(&cx, parser)
236 })
237 }
238
239 #[inline]
245 pub fn decode_with<'de, C, P, T>(self, cx: &C, parser: P) -> Result<T, C::Error>
246 where
247 C: ?Sized + Context<Mode = M>,
248 P: Parser<'de>,
249 T: Decode<'de, M>,
250 {
251 cx.clear();
252 JsonDecoder::new(cx, parser).decode()
253 }
254
255 #[inline]
258 pub fn from_str<'de, T>(self, string: &'de str) -> Result<T, Error>
259 where
260 T: Decode<'de, M>,
261 {
262 self.from_slice(string.as_bytes())
263 }
264
265 #[inline]
271 pub fn from_str_with<'de, C, T>(self, cx: &C, string: &'de str) -> Result<T, C::Error>
272 where
273 C: ?Sized + Context<Mode = M>,
274 T: Decode<'de, M>,
275 {
276 self.from_slice_with(cx, string.as_bytes())
277 }
278
279 #[inline]
282 pub fn from_slice<'de, T>(self, bytes: &'de [u8]) -> Result<T, Error>
283 where
284 T: Decode<'de, M>,
285 {
286 musli_utils::allocator::with(|alloc| {
287 let cx = musli_utils::context::Same::<_, M, _>::new(alloc);
288 self.from_slice_with(&cx, bytes)
289 })
290 }
291
292 #[inline]
298 pub fn from_slice_with<'de, C, T>(self, cx: &C, bytes: &'de [u8]) -> Result<T, C::Error>
299 where
300 C: ?Sized + Context<Mode = M>,
301 T: Decode<'de, M>,
302 {
303 cx.clear();
304 JsonDecoder::new(cx, SliceParser::new(bytes)).decode()
305 }
306
307 musli_utils::encode_with_extensions!(M);
308}
309
310impl<M> Clone for Encoding<M> {
311 #[inline]
312 fn clone(&self) -> Self {
313 *self
314 }
315}
316
317impl<M> Copy for Encoding<M> {}