musli/macros/
internal.rs

1//! Helper macros for use with Musli.
2
3macro_rules! bare_encoding {
4    ($mode:ident, $default:ident, $what:ident, $reader_trait:ident) => {
5        /// Encode the given value to the given [`Writer`] using the [`DEFAULT`]
6        /// [`Encoding`].
7        ///
8        /// [`Writer`]: crate::Writer
9        ///
10        /// # Examples
11        ///
12        /// ```
13        /// use musli::{Decode, Encode};
14        #[doc = concat!("use musli::", stringify!($what), ";")]
15        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
16        ///
17        /// #[derive(Decode, Encode)]
18        /// struct Person {
19        ///     name: String,
20        ///     age: u32,
21        /// }
22        ///
23        /// let mut data = Vec::new();
24        ///
25        #[doc = concat!(stringify!($what), "::encode(&mut data, &Person {")]
26        ///     name: "Aristotle".to_string(),
27        ///     age: 61,
28        /// })?;
29        ///
30        #[doc = concat!("let person: Person = ", stringify!($what), "::from_slice(&data[..])?;")]
31        /// assert_eq!(person.name, "Aristotle");
32        /// assert_eq!(person.age, 61);
33        /// # Ok::<(), Error>(())
34        /// ```
35        #[inline]
36        pub fn encode<W, T>(writer: W, value: &T) -> Result<(), Error>
37        where
38            W: $crate::Writer,
39            T: ?Sized + $crate::Encode<crate::mode::$mode>,
40        {
41            $default.encode(writer, value)
42        }
43
44        /// Encode the given value to a [`Vec`] using the [`DEFAULT`]
45        /// [`Encoding`].
46        ///
47        /// [`Vec`]: rust_alloc::vec::Vec
48        ///
49        /// # Examples
50        ///
51        /// ```
52        /// use musli::{Decode, Encode};
53        #[doc = concat!("use musli::", stringify!($what), ";")]
54        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
55        ///
56        /// #[derive(Decode, Encode)]
57        /// struct Person {
58        ///     name: String,
59        ///     age: u32,
60        /// }
61        ///
62        #[doc = concat!("let data = ", stringify!($what), "::to_vec(&Person {")]
63        ///     name: "Aristotle".to_string(),
64        ///     age: 61,
65        /// })?;
66        ///
67        #[doc = concat!("let person: Person = ", stringify!($what), "::from_slice(&data[..])?;")]
68        /// assert_eq!(person.name, "Aristotle");
69        /// assert_eq!(person.age, 61);
70        /// # Ok::<(), Error>(())
71        /// ```
72        #[cfg(feature = "alloc")]
73        #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
74        #[inline]
75        pub fn to_vec<T>(value: &T) -> Result<rust_alloc::vec::Vec<u8>, Error>
76        where
77            T: ?Sized + $crate::Encode<crate::mode::$mode>,
78        {
79            $default.to_vec(value)
80        }
81
82        /// Encode the given value to a fixed-size bytes using the [`DEFAULT`]
83        /// [`Encoding`].
84        ///
85        /// ```
86        /// use musli::{Decode, Encode, FixedBytes};
87        #[doc = concat!("use musli::", stringify!($what), ";")]
88        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
89        ///
90        /// #[derive(Decode, Encode)]
91        /// struct Person {
92        ///     name: String,
93        ///     age: u32,
94        /// }
95        ///
96        #[doc = concat!("let data: FixedBytes<128> = ", stringify!($what), "::to_fixed_bytes(&Person {")]
97        ///     name: "Aristotle".to_string(),
98        ///     age: 61,
99        /// })?;
100        ///
101        #[doc = concat!("let person: Person = ", stringify!($what), "::from_slice(&data[..])?;")]
102        /// assert_eq!(person.name, "Aristotle");
103        /// assert_eq!(person.age, 61);
104        /// # Ok::<(), Error>(())
105        /// ```
106        #[inline]
107        pub fn to_fixed_bytes<const N: usize, T>(value: &T) -> Result<$crate::FixedBytes<N>, Error>
108        where
109            T: ?Sized + $crate::Encode<crate::mode::$mode>,
110        {
111            $default.to_fixed_bytes::<N, _>(value)
112        }
113
114        /// Encode the given value to the given [`Write`] using the [`DEFAULT`]
115        /// [`Encoding`].
116        ///
117        /// [`Write`]: std::io::Write
118        ///
119        /// # Examples
120        ///
121        /// ```
122        /// use musli::{Decode, Encode};
123        #[doc = concat!("use musli::", stringify!($what), ";")]
124        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
125        ///
126        /// #[derive(Decode, Encode)]
127        /// struct Person {
128        ///     name: String,
129        ///     age: u32,
130        /// }
131        ///
132        /// let mut data = Vec::new();
133        ///
134        #[doc = concat!(stringify!($what), "::to_writer(&mut data, &Person {")]
135        ///     name: "Aristotle".to_string(),
136        ///     age: 61,
137        /// })?;
138        ///
139        #[doc = concat!("let person: Person = ", stringify!($what), "::from_slice(&data[..])?;")]
140        /// assert_eq!(person.name, "Aristotle");
141        /// assert_eq!(person.age, 61);
142        /// # Ok::<(), Error>(())
143        /// ```
144        #[cfg(feature = "std")]
145        #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
146        #[inline]
147        pub fn to_writer<W, T>(writer: W, value: &T) -> Result<(), Error>
148        where
149            W: std::io::Write,
150            T: ?Sized + $crate::Encode<crate::mode::$mode>,
151        {
152            $default.to_writer(writer, value)
153        }
154
155        /// Decode the given type `T` from the given [`Reader`] using the [`DEFAULT`]
156        /// [`Encoding`].
157        ///
158        /// [`Reader`]: crate::Reader
159        ///
160        /// # Examples
161        ///
162        /// ```
163        /// use musli::{Decode, Encode};
164        #[doc = concat!("use musli::", stringify!($what), ";")]
165        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
166        ///
167        /// #[derive(Decode, Encode)]
168        /// struct Person {
169        ///     name: String,
170        ///     age: u32,
171        /// }
172        ///
173        #[doc = concat!("let mut data = ", stringify!($what), "::to_vec(&Person {")]
174        ///     name: "Aristotle".to_string(),
175        ///     age: 61,
176        /// })?;
177        ///
178        /// // Add some extra data which will be ignored during decoding.
179        /// data.extend_from_slice(&[0xde, 0xad, 0xbe, 0xef]);
180        ///
181        /// // Note: A slice implements `musli::Reader`.
182        /// let mut slice = &data[..];
183        ///
184        #[doc = concat!("let person: Person = ", stringify!($what), "::decode(&mut slice)?;")]
185        /// assert_eq!(slice, &[0xde, 0xad, 0xbe, 0xef]);
186        /// assert_eq!(person.name, "Aristotle");
187        /// assert_eq!(person.age, 61);
188        /// # Ok::<(), Error>(())
189        /// ```
190        #[inline]
191        pub fn decode<'de, R, T>(reader: R) -> Result<T, Error>
192        where
193            R: $reader_trait<'de>,
194            T: $crate::Decode<'de, $mode>,
195        {
196            $default.decode(reader)
197        }
198
199        /// Decode the given type `T` from the given slice using the [`DEFAULT`]
200        /// [`Encoding`].
201        ///
202        /// # Examples
203        ///
204        /// ```
205        /// use musli::{Decode, Encode};
206        #[doc = concat!("use musli::", stringify!($what), ";")]
207        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
208        ///
209        /// #[derive(Decode, Encode)]
210        /// struct Person {
211        ///     name: String,
212        ///     age: u32,
213        /// }
214        ///
215        #[doc = concat!("let data = ", stringify!($what), "::to_vec(&Person {")]
216        ///     name: "Aristotle".to_string(),
217        ///     age: 61,
218        /// })?;
219        ///
220        #[doc = concat!("let person: Person = ", stringify!($what), "::from_slice(&data[..])?;")]
221        /// assert_eq!(person.name, "Aristotle");
222        /// assert_eq!(person.age, 61);
223        /// # Ok::<(), Error>(())
224        /// ```
225        #[inline]
226        pub fn from_slice<'de, T>(bytes: &'de [u8]) -> Result<T, Error>
227        where
228            T: $crate::Decode<'de, $mode>,
229        {
230            $default.from_slice(bytes)
231        }
232    };
233}
234
235pub(crate) use bare_encoding;
236
237/// Generate all public encoding helpers.
238macro_rules! encoding_impls {
239    ($mode:ident, $what:ident, $encoder_new:path, $decoder_new:path, $reader_trait:ident :: $into_reader:ident $(,)?) => {
240        /// Encode the given value to the given [`Writer`] using the current
241        /// [`Encoding`].
242        ///
243        /// [`Writer`]: crate::Writer
244        ///
245        /// # Examples
246        ///
247        /// ```
248        /// use musli::{Decode, Encode};
249        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
250        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
251        ///
252        /// const ENCODING: Encoding = Encoding::new();
253        ///
254        /// #[derive(Decode, Encode)]
255        /// struct Person {
256        ///     name: String,
257        ///     age: u32,
258        /// }
259        ///
260        /// let mut data = Vec::new();
261        ///
262        /// ENCODING.encode(&mut data, &Person {
263        ///     name: "Aristotle".to_string(),
264        ///     age: 61,
265        /// })?;
266        ///
267        /// let person: Person = ENCODING.from_slice(&data[..])?;
268        /// assert_eq!(person.name, "Aristotle");
269        /// assert_eq!(person.age, 61);
270        /// # Ok::<(), Error>(())
271        /// ```
272        #[inline]
273        pub fn encode<W, T>(self, writer: W, value: &T) -> Result<(), Error>
274        where
275            W: $crate::Writer,
276            T: ?Sized + $crate::Encode<$mode>,
277        {
278            $crate::alloc::default!(|alloc| {
279                let cx = $crate::context::Same::with_alloc(alloc);
280                self.encode_with(&cx, writer, value)
281            })
282        }
283
284        /// Encode the given value to a [`Vec`] using the current [`Encoding`].
285        ///
286        /// [`Vec`]: rust_alloc::vec::Vec
287        ///
288        /// # Examples
289        ///
290        /// ```
291        /// use musli::{Decode, Encode};
292        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
293        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
294        ///
295        /// const ENCODING: Encoding = Encoding::new();
296        ///
297        /// #[derive(Decode, Encode)]
298        /// struct Person {
299        ///     name: String,
300        ///     age: u32,
301        /// }
302        ///
303        /// let data = ENCODING.to_vec(&Person {
304        ///     name: "Aristotle".to_string(),
305        ///     age: 61,
306        /// })?;
307        ///
308        /// let person: Person = ENCODING.from_slice(&data[..])?;
309        /// assert_eq!(person.name, "Aristotle");
310        /// assert_eq!(person.age, 61);
311        /// # Ok::<(), Error>(())
312        /// ```
313        #[cfg(feature = "alloc")]
314        #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
315        #[inline]
316        pub fn to_vec<T>(self, value: &T) -> Result<rust_alloc::vec::Vec<u8>, Error>
317        where
318            T: ?Sized + $crate::Encode<$mode>,
319        {
320            let mut vec = rust_alloc::vec::Vec::new();
321            self.encode(&mut vec, value)?;
322            Ok(vec)
323        }
324
325        /// Encode the given value to a fixed-size bytes using the current
326        /// [`Encoding`].
327        ///
328        /// # Examples
329        ///
330        /// ```
331        /// use musli::{Decode, Encode, FixedBytes};
332        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
333        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
334        ///
335        /// const ENCODING: Encoding = Encoding::new();
336        ///
337        /// #[derive(Decode, Encode)]
338        /// struct Person {
339        ///     name: String,
340        ///     age: u32,
341        /// }
342        ///
343        /// let data: FixedBytes<128> = ENCODING.to_fixed_bytes(&Person {
344        ///     name: "Aristotle".to_string(),
345        ///     age: 61,
346        /// })?;
347        ///
348        /// let person: Person = ENCODING.from_slice(&data[..])?;
349        /// assert_eq!(person.name, "Aristotle");
350        /// assert_eq!(person.age, 61);
351        /// # Ok::<(), Error>(())
352        /// ```
353        #[inline]
354        pub fn to_fixed_bytes<const N: usize, T>(
355            self,
356            value: &T,
357        ) -> Result<$crate::FixedBytes<N>, Error>
358        where
359            T: ?Sized + $crate::Encode<$mode>,
360        {
361            $crate::alloc::default!(|alloc| {
362                let cx = $crate::context::Same::with_alloc(alloc);
363                self.to_fixed_bytes_with(&cx, value)
364            })
365        }
366
367        /// Encode the given value to the given [`Write`] using the current
368        /// [`Encoding`].
369        ///
370        /// [`Write`]: std::io::Write
371        ///
372        /// # Examples
373        ///
374        /// ```
375        /// use musli::{Decode, Encode};
376        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
377        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
378        ///
379        /// const ENCODING: Encoding = Encoding::new();
380        ///
381        /// #[derive(Decode, Encode)]
382        /// struct Person {
383        ///     name: String,
384        ///     age: u32,
385        /// }
386        ///
387        /// let mut data = Vec::new();
388        ///
389        /// ENCODING.to_writer(&mut data, &Person {
390        ///     name: "Aristotle".to_string(),
391        ///     age: 61,
392        /// })?;
393        ///
394        /// let person: Person = ENCODING.from_slice(&data[..])?;
395        /// assert_eq!(person.name, "Aristotle");
396        /// assert_eq!(person.age, 61);
397        /// # Ok::<(), Error>(())
398        /// ```
399        #[cfg(feature = "std")]
400        #[inline]
401        pub fn to_writer<W, T>(self, write: W, value: &T) -> Result<(), Error>
402        where
403            W: std::io::Write,
404            T: ?Sized + $crate::Encode<$mode>,
405        {
406            let writer = $crate::wrap::wrap(write);
407            self.encode(writer, value)
408        }
409
410        /// Decode the given type `T` from the given [`Reader`] using the
411        /// current [`Encoding`].
412        ///
413        /// [`Reader`]: crate::Reader
414        ///
415        /// # Examples
416        ///
417        /// ```
418        /// use musli::{Decode, Encode};
419        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
420        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
421        ///
422        /// const ENCODING: Encoding = Encoding::new();
423        ///
424        /// #[derive(Decode, Encode)]
425        /// struct Person {
426        ///     name: String,
427        ///     age: u32,
428        /// }
429        ///
430        /// let mut data = ENCODING.to_vec(&Person {
431        ///     name: "Aristotle".to_string(),
432        ///     age: 61,
433        /// })?;
434        ///
435        /// // Add some extra data which will be ignored during decoding.
436        /// data.extend_from_slice(&[0xde, 0xad, 0xbe, 0xef]);
437        ///
438        /// // Note: A slice implements `musli::Reader`.
439        /// let mut slice = &data[..];
440        /// let person: Person = ENCODING.decode(&mut slice)?;
441        ///
442        /// assert_eq!(slice, &[0xde, 0xad, 0xbe, 0xef]);
443        /// assert_eq!(person.name, "Aristotle");
444        /// assert_eq!(person.age, 61);
445        /// # Ok::<(), Error>(())
446        /// ```
447        #[inline]
448        pub fn decode<'de, R, T>(self, reader: R) -> Result<T, Error>
449        where
450            R: $reader_trait<'de>,
451            T: $crate::Decode<'de, $mode>,
452        {
453            $crate::alloc::default!(|alloc| {
454                let cx = $crate::context::Same::with_alloc(alloc);
455                self.decode_with(&cx, reader)
456            })
457        }
458
459        /// Decode the given type `T` from the given slice using the current
460        /// [`Encoding`].
461        ///
462        /// # Examples
463        ///
464        /// ```
465        /// use musli::{Decode, Encode};
466        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
467        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
468        ///
469        /// const ENCODING: Encoding = Encoding::new();
470        ///
471        /// #[derive(Decode, Encode)]
472        /// struct Person {
473        ///     name: String,
474        ///     age: u32,
475        /// }
476        ///
477        /// let data = ENCODING.to_vec(&Person {
478        ///     name: "Aristotle".to_string(),
479        ///     age: 61,
480        /// })?;
481        ///
482        /// let person: Person = ENCODING.from_slice(&data[..])?;
483        /// assert_eq!(person.name, "Aristotle");
484        /// assert_eq!(person.age, 61);
485        /// # Ok::<(), Error>(())
486        /// ```
487        #[inline]
488        pub fn from_slice<'de, T>(self, bytes: &'de [u8]) -> Result<T, Error>
489        where
490            T: $crate::Decode<'de, $mode>,
491        {
492            $crate::alloc::default!(|alloc| {
493                let cx = $crate::context::Same::with_alloc(alloc);
494                self.from_slice_with(&cx, bytes)
495            })
496        }
497
498        /// Decode the given type `T` from the given string using the current
499        /// [`Encoding`].
500        ///
501        /// This is an alias over [`Encoding::from_slice`] for convenience. See
502        /// its documentation for more.
503        #[inline]
504        pub fn from_str<'de, T>(self, string: &'de str) -> Result<T, Error>
505        where
506            T: $crate::Decode<'de, M>,
507        {
508            self.from_slice(string.as_bytes())
509        }
510
511        /// Encode the given value to the given [`Writer`] using the current
512        /// [`Encoding`].
513        ///
514        /// This is the same as [`Encoding::encode`] but allows for using a
515        /// configurable [`Context`].
516        ///
517        /// [`Writer`]: crate::Writer
518        /// [`Context`]: crate::Context
519        ///
520        /// # Examples
521        ///
522        /// ```
523        /// use musli::{Decode, Encode};
524        /// use musli::alloc::System;
525        /// use musli::context::Same;
526        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
527        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
528        ///
529        /// const ENCODING: Encoding = Encoding::new();
530        ///
531        /// #[derive(Decode, Encode)]
532        /// struct Person {
533        ///     name: String,
534        ///     age: u32,
535        /// }
536        ///
537        /// let cx = Same::new();
538        ///
539        /// let mut data = Vec::new();
540        ///
541        /// ENCODING.encode_with(&cx, &mut data, &Person {
542        ///     name: "Aristotle".to_string(),
543        ///     age: 61,
544        /// })?;
545        ///
546        /// let person: Person = ENCODING.from_slice_with(&cx, &data[..])?;
547        /// assert_eq!(person.name, "Aristotle");
548        /// assert_eq!(person.age, 61);
549        /// # Ok::<(), Error>(())
550        /// ```
551        #[inline]
552        pub fn encode_with<C, W, T>(self, cx: &C, writer: W, value: &T) -> Result<(), C::Error>
553        where
554            C: ?Sized + $crate::Context<Mode = $mode>,
555            W: $crate::Writer,
556            T: ?Sized + $crate::Encode<C::Mode>,
557        {
558            cx.clear();
559            T::encode(value, cx, $encoder_new(cx, writer))
560        }
561
562        /// Encode the given value to a [`Vec`] using the current [`Encoding`].
563        ///
564        /// This is the same as [`Encoding::to_vec`], but allows for using a
565        /// configurable [`Context`].
566        ///
567        /// [`Context`]: crate::Context
568        /// [`Vec`]: rust_alloc::vec::Vec
569        ///
570        /// # Examples
571        ///
572        /// ```
573        /// use musli::{Decode, Encode};
574        /// use musli::alloc::System;
575        /// use musli::context::Same;
576        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
577        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
578        ///
579        /// const ENCODING: Encoding = Encoding::new();
580        ///
581        /// #[derive(Decode, Encode)]
582        /// struct Person {
583        ///     name: String,
584        ///     age: u32,
585        /// }
586        ///
587        /// let cx = Same::new();
588        ///
589        /// let data = ENCODING.to_vec_with(&cx, &Person {
590        ///     name: "Aristotle".to_string(),
591        ///     age: 61,
592        /// })?;
593        ///
594        /// let person: Person = ENCODING.from_slice_with(&cx, &data[..])?;
595        /// assert_eq!(person.name, "Aristotle");
596        /// assert_eq!(person.age, 61);
597        /// # Ok::<(), Error>(())
598        /// ```
599        #[cfg(feature = "alloc")]
600        #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
601        #[inline]
602        pub fn to_vec_with<C, T>(
603            self,
604            cx: &C,
605            value: &T,
606        ) -> Result<rust_alloc::vec::Vec<u8>, C::Error>
607        where
608            C: ?Sized + $crate::Context<Mode = $mode>,
609            T: ?Sized + $crate::Encode<C::Mode>,
610        {
611            let mut vec = rust_alloc::vec::Vec::new();
612            self.encode_with(cx, &mut vec, value)?;
613            Ok(vec)
614        }
615
616        /// Encode the given value to a fixed-size bytes using the current
617        /// [`Encoding`].
618        ///
619        /// # Examples
620        ///
621        /// ```
622        /// use musli::{Decode, Encode, FixedBytes};
623        /// use musli::alloc::System;
624        /// use musli::context::Same;
625        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
626        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
627        ///
628        /// const ENCODING: Encoding = Encoding::new();
629        ///
630        /// #[derive(Decode, Encode)]
631        /// struct Person {
632        ///     name: String,
633        ///     age: u32,
634        /// }
635        ///
636        /// let cx = Same::new();
637        ///
638        /// let data: FixedBytes<128> = ENCODING.to_fixed_bytes_with(&cx, &Person {
639        ///     name: "Aristotle".to_string(),
640        ///     age: 61,
641        /// })?;
642        ///
643        /// let person: Person = ENCODING.from_slice_with(&cx, &data[..])?;
644        /// assert_eq!(person.name, "Aristotle");
645        /// assert_eq!(person.age, 61);
646        /// # Ok::<(), Error>(())
647        /// ```
648        #[inline]
649        pub fn to_fixed_bytes_with<C, const N: usize, T>(
650            self,
651            cx: &C,
652            value: &T,
653        ) -> Result<$crate::FixedBytes<N>, C::Error>
654        where
655            C: ?Sized + $crate::Context<Mode = $mode>,
656            T: ?Sized + $crate::Encode<C::Mode>,
657        {
658            let mut bytes = $crate::FixedBytes::new();
659            self.encode_with(cx, &mut bytes, value)?;
660            Ok(bytes)
661        }
662
663        /// Encode the given value to the given [`Write`] using the current
664        /// [`Encoding`] and context `C`.
665        ///
666        /// [`Write`]: std::io::Write
667        ///
668        /// # Examples
669        ///
670        /// ```
671        /// use musli::{Decode, Encode};
672        /// use musli::alloc::System;
673        /// use musli::context::Same;
674        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
675        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
676        ///
677        /// const ENCODING: Encoding = Encoding::new();
678        ///
679        /// #[derive(Decode, Encode)]
680        /// struct Person {
681        ///     name: String,
682        ///     age: u32,
683        /// }
684        ///
685        /// let cx = Same::new();
686        ///
687        /// let mut data = Vec::new();
688        ///
689        /// ENCODING.to_writer_with(&cx, &mut data, &Person {
690        ///     name: "Aristotle".to_string(),
691        ///     age: 61,
692        /// })?;
693        ///
694        /// let person: Person = ENCODING.from_slice_with(&cx, &data[..])?;
695        /// assert_eq!(person.name, "Aristotle");
696        /// assert_eq!(person.age, 61);
697        /// # Ok::<(), Error>(())
698        /// ```
699        #[cfg(feature = "std")]
700        #[inline]
701        pub fn to_writer_with<C, W, T>(self, cx: &C, write: W, value: &T) -> Result<(), C::Error>
702        where
703            C: ?Sized + $crate::Context<Mode = $mode>,
704            W: std::io::Write,
705            T: ?Sized + $crate::Encode<C::Mode>,
706        {
707            let writer = $crate::wrap::wrap(write);
708            self.encode_with(cx, writer, value)
709        }
710
711        /// Decode the given type `T` from the given [`Reader`] using the
712        /// current [`Encoding`].
713        ///
714        /// This is the same as [`Encoding::decode`] but allows for using a
715        /// configurable [`Context`].
716        ///
717        /// [`Reader`]: crate::Reader
718        /// [`Context`]: crate::Context
719        ///
720        /// # Examples
721        ///
722        /// ```
723        /// use musli::{Decode, Encode};
724        /// use musli::alloc::System;
725        /// use musli::context::Same;
726        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
727        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
728        ///
729        /// const ENCODING: Encoding = Encoding::new();
730        ///
731        /// #[derive(Decode, Encode)]
732        /// struct Person {
733        ///     name: String,
734        ///     age: u32,
735        /// }
736        ///
737        /// let cx = Same::new();
738        ///
739        /// let buf = ENCODING.to_vec_with(&cx, &Person {
740        ///     name: "Aristotle".to_string(),
741        ///     age: 61,
742        /// })?;
743        ///
744        /// let mut slice = &buf[..];
745        /// let person: Person = ENCODING.decode_with(&cx, &mut slice)?;
746        /// assert_eq!(person.name, "Aristotle");
747        /// assert_eq!(person.age, 61);
748        /// # Ok::<(), Error>(())
749        /// ```
750        #[inline]
751        pub fn decode_with<'de, C, R, T>(self, cx: &C, reader: R) -> Result<T, C::Error>
752        where
753            C: ?Sized + $crate::Context<Mode = $mode>,
754            R: $reader_trait<'de>,
755            T: $crate::Decode<'de, C::Mode>,
756        {
757            cx.clear();
758            let reader = $reader_trait::$into_reader(reader);
759            T::decode(cx, $decoder_new(cx, reader))
760        }
761
762        /// Decode the given type `T` from the given slice using the current
763        /// [`Encoding`].
764        ///
765        /// This is the same as [`Encoding::from_slice`], but allows for using a
766        /// configurable [`Context`].
767        ///
768        /// [`Context`]: crate::Context
769        ///
770        /// # Examples
771        ///
772        /// ```
773        /// use musli::{Decode, Encode};
774        /// use musli::alloc::System;
775        /// use musli::context::Same;
776        #[doc = concat!("use musli::", stringify!($what), "::Encoding;")]
777        #[doc = concat!("# use musli::", stringify!($what), "::Error;")]
778        ///
779        /// const ENCODING: Encoding = Encoding::new();
780        ///
781        /// #[derive(Decode, Encode)]
782        /// struct Person {
783        ///     name: String,
784        ///     age: u32,
785        /// }
786        ///
787        /// let cx = Same::new();
788        ///
789        /// let buf = ENCODING.to_vec_with(&cx, &Person {
790        ///     name: "Aristotle".to_string(),
791        ///     age: 61,
792        /// })?;
793        ///
794        /// let person: Person = ENCODING.from_slice_with(&cx, &buf[..])?;
795        /// assert_eq!(person.name, "Aristotle");
796        /// assert_eq!(person.age, 61);
797        /// # Ok::<(), Error>(())
798        /// ```
799        #[inline]
800        pub fn from_slice_with<'de, C, T>(self, cx: &C, bytes: &'de [u8]) -> Result<T, C::Error>
801        where
802            C: ?Sized + $crate::Context<Mode = $mode>,
803            T: $crate::Decode<'de, $mode>,
804        {
805            self.decode_with(cx, bytes)
806        }
807
808        /// Decode the given type `T` from the given string using the current
809        /// [`Encoding`].
810        ///
811        /// This is the same as [`Encoding::from_str`] but allows for using a
812        /// configurable [`Context`].
813        ///
814        /// This is an alias over [`Encoding::from_slice_with`] for convenience.
815        /// See its documentation for more.
816        ///
817        /// [`Context`]: crate::Context
818        #[inline]
819        pub fn from_str_with<'de, C, T>(self, cx: &C, string: &'de str) -> Result<T, C::Error>
820        where
821            C: ?Sized + $crate::Context<Mode = M>,
822            T: $crate::Decode<'de, M>,
823        {
824            self.from_slice_with(cx, string.as_bytes())
825        }
826    };
827}
828
829pub(crate) use encoding_impls;