musli/help/
derives.rs

1//! Deriving [`Encode`] and [`Decode`].
2//!
3//! The [`Encode`] and [`Decode`] derives allows for automatically implementing
4//! [`Encode`] and [`Decode`].
5//!
6//! They come with a number of options for customizing their implementation,
7//! detailed below. But first we need to talk about *modes*.
8//!
9//! <br>
10//!
11//! #### Modes
12//!
13//! If you've paid close attention to the [`Encode`] and [`Decode`] traits you
14//! might notive that they have an extra parameter called `M`. This stands for
15//! "mode".
16//!
17//! This parameter allows us to have different implementations of these traits
18//! for the same type.
19//!
20//! By default we implements two modes, which each have subtly different default
21//! behaviors:
22//! * [`Binary`] - which uses indexed fields, the equivalent of
23//!   `#[musli(name_type = usize)]`.
24//! * [`Text`] - which uses literally text fields by their name, the equivalent
25//!   of `#[musli(name_type = str)]`.
26//!
27//! When it comes to deriving these traits you can scope attributes to apply to
28//! any mode including custom local ones. This is done using the `#[musli(mode =
29//! ..)]` meta attribute like this:
30//!
31//! ```
32//! use musli::{Encode, Decode};
33//! use musli::mode::Binary;
34//! use musli::json::Encoding;
35//!
36//! #[derive(Encode, Decode)]
37//! struct Person<'a> {
38//!     #[musli(mode = Text, name = "name")]
39//!     not_name: &'a str,
40//!     age: u32,
41//! }
42//!
43//! const TEXT: Encoding = Encoding::new();
44//! const BINARY: Encoding<Binary> = Encoding::new().with_mode();
45//!
46//! let named = TEXT.to_vec(&Person { not_name: "Aristotle", age: 61 })?;
47//! assert_eq!(named.as_slice(), br#"{"name":"Aristotle","age":61}"#);
48//!
49//! let indexed = BINARY.to_vec(&Person { not_name: "Plato", age: 84 })?;
50//! assert_eq!(indexed.as_slice(), br#"{"0":"Plato","1":84}"#);
51//! # Ok::<_, musli::json::Error>(())
52//! ```
53//!
54//! So the `#[musli(mode)]` atttribute is supported in any position. And any of
55//! its sibling attributes will be added to the given *alternative* mode, rather
56//! the [default mode].
57//!
58//! <br>
59//!
60//! #### Attributes
61//!
62//! * [*Meta attributes*](#meta-attributes) which apply to the attribute itself.
63//!   It is used to filter what scope the current attribute applies to, such as
64//!   only applying to an `Encode` derive using `#[musli(encode_only, ..)]` or a
65//!   specific mode such as `#[musli(mode = Json, ..)]`.
66//!
67//! * [*Container attributes*](#container-attributes) are attributes which apply
68//!   to the `struct` or `enum`.
69//!
70//! * [*Variant attributes*](#variant-attributes) are attributes which apply to
71//!   each individual variant in an `enum`.
72//!
73//! * [*Field attributes*](#field-attributes) are attributes which apply to each
74//!   individual field either in a `struct` or an `enum` variant.
75//!
76//! <br>
77//!
78//! ## Meta attributes
79//!
80//! Certain attributes affect which other attributes apply to a given context.
81//! These are called *meta* attributes.
82//!
83//! Meta attributes are applicable to any context, and can be used on
84//! containers, variants, and fields.
85//!
86//! <br>
87//!
88//! #### `#[musli(mode = <path>)]`
89//!
90//! The attributes only apply to the given `mode`.
91//!
92//! The `Person` struct below uses string field names by default when the `Text`
93//! mode is enabled, but we can change this behavior only for that particular
94//! mode like this:
95//!
96//! ```
97//! use musli::{Encode, Decode};
98//! use musli::mode::Text;
99//!
100//! #[derive(Encode, Decode)]
101//! #[musli(mode = Text, name_type = usize)]
102//! struct Person<'a> {
103//!     name: &'a str,
104//!     age: u32,
105//! }
106//! ```
107//!
108//! <br>
109//!
110//! #### `#[musli(encode_only)]`
111//!
112//! The attributes only apply when implementing the `Encode` trait.
113//!
114//! An example where this is useful is if you want to apply `#[musli(packed)]`
115//! in a different mode, but only for encoding, since decoding packed types is
116//! not supported for enums.
117//!
118//! ```
119//! use musli::mode::Binary;
120//! use musli::{Decode, Encode};
121//!
122//! enum Packed {}
123//!
124//! #[derive(Encode, Decode)]
125//! #[musli(mode = Packed, encode_only, packed)]
126//! enum Name<'a> {
127//!     Full(&'a str),
128//!     Given(&'a str),
129//! }
130//! ```
131//!
132//! <br>
133//!
134//! #### `#[musli(decode_only)]`
135//!
136//! The attributes only apply when implementing the `Decode` trait.
137//!
138//! ```
139//! use musli::{Decode, Encode};
140//!
141//! #[derive(Encode, Decode)]
142//! #[musli(name_all = "name")]
143//! struct Name<'a> {
144//!     sur_name: &'a str,
145//!     #[musli(decode_only, name = "last")]
146//!     last_name: &'a str,
147//! }
148//! ```
149//!
150//! <br>
151//!
152//! ## Container attributes
153//!
154//! Container attributes apply to the container, such as directly on the
155//! `struct` or `enum`. Like the uses of `#[musli(packed)]` and
156//! `#[musli(name_all = "name")]` here:
157//!
158//! ```
159//! use musli::{Encode, Decode};
160//!
161//! #[derive(Encode, Decode)]
162//! #[musli(packed)]
163//! struct Struct {
164//!     /* the body of the struct */
165//! }
166//!
167//! #[derive(Encode, Decode)]
168//! #[musli(name_all = "name")]
169//! enum Enum {
170//!     /* the body of the enum */
171//! }
172//! ```
173//!
174//! <br>
175//!
176//! #### `#[musli(name_all = "..")]`
177//!
178//! Allos for renaming every field in the container. It can take any of the
179//! following values:
180//!
181//! * `index` (default) - the index of the field will be used.
182//! * `name` - the literal name of the field will be used.
183//! * `PascalCase` - the field will be converted to pascal case.
184//! * `camelCase` - the field will be converted to camel case.
185//! * `snake_case` - the field will be converted to snake case.
186//! * `SCREAMING_SNAKE_CASE` - the field will be converted to screaming snake case.
187//! * `kebab-case` - the field will be converted to kebab case.
188//! * `SCREAMING-KEBAB-CASE` - the field will be converted to screaming kebab case.
189//!
190//! ```
191//! use musli::{Encode, Decode};
192//!
193//! #[derive(Encode, Decode)]
194//! #[musli(name_all = "PascalCase")]
195//! struct PascalCaseStruct {
196//!     field_name: u32,
197//! }
198//!
199//! #[derive(Encode, Decode)]
200//! #[musli(name_all = "name")]
201//! struct NamedStruct {
202//!     field1: u32,
203//!     field2: u32,
204//! }
205//! ```
206//!
207//! If applied to an enum, it will instead rename all variants:
208//!
209//! ```
210//! use musli::{Encode, Decode};
211//!
212//! #[derive(Encode, Decode)]
213//! #[musli(name_all = "PascalCase")]
214//! enum PascalCaseEnum {
215//!     VariantName {
216//!         field_name: u32,
217//!     }
218//! }
219//!
220//! #[derive(Encode, Decode)]
221//! #[musli(name_all = "name")]
222//! enum NamedEnum {
223//!     Variant1 {
224//!         field1: u32,
225//!     },
226//!     Variant2 {
227//!         field1: u32,
228//!     },
229//! }
230//! ```
231//!
232//! <br>
233//!
234//! #### `#[musli(transparent)]`
235//!
236//! This can only be used on types which have a single field. It will cause that
237//! field to define how that variant is encoded or decoded transparently without
238//! being treated as a field.
239//!
240//! ```
241//! use musli::{Encode, Decode};
242//!
243//! #[derive(Encode)]
244//! #[musli(transparent)]
245//! struct Struct(u32);
246//!
247//! let data = musli::wire::to_vec(&Struct(42))?;
248//! let actual: u32 = musli::wire::from_slice(&data)?;
249//! assert_eq!(actual, 42u32);
250//! # Ok::<_, musli::wire::Error>(())
251//! ```
252//!
253//! <br>
254//!
255//! #### `#[musli(packed)]`
256//!
257//! This attribute will disable all *tagging* and the structure will simply be
258//! encoded with one field following another in the order in which they are
259//! defined.
260//!
261//! A caveat of *packed* structures is that they cannot be safely versioned and
262//! the two systems communicating through them need to be using strictly
263//! synchronized representations.
264//!
265//! This attribute is useful for performing simple decoding over "raw" bytes
266//! when combined with an encoder which does minimal prefixing and packs fields.
267//!
268//! ```
269//! use musli::{Encode, Decode};
270//!
271//! #[derive(Encode)]
272//! #[musli(packed)]
273//! struct Struct {
274//!     field1: u32,
275//!     field2: u32,
276//!     field3: u32,
277//! }
278//!
279//! let data = musli::storage::to_vec(&Struct {
280//!     field1: 1,
281//!     field2: 2,
282//!     field3: 3,
283//! })?;
284//!
285//! assert_eq!(data.as_slice(), [1, 2, 3]);
286//! # Ok::<_, musli::storage::Error>(())
287//! ```
288//!
289//! <br>
290//!
291//! #### `#[musli(name_type = ..)]`
292//!
293//! This indicates which type any contained `#[musli(name = ..)]` attributes
294//! should have. Tags can usually be inferred, but specifying this field ensures
295//! that all tags have a single well-defined type.
296//!
297//! The following values are treated specially:
298//! * `str` applies `#[musli(name_all = "name")]` by default.
299//! * `[u8]` applies `#[musli(name_all = "name")]` by default.
300//!
301//! ```
302//! use core::fmt;
303//!
304//! use musli::{Encode, Decode};
305//!
306//! #[derive(Debug, PartialEq, Eq, Encode, Decode)]
307//! #[musli(transparent)]
308//! struct CustomTag<'a>(&'a [u8]);
309//!
310//! impl fmt::Display for CustomTag<'_> {
311//!     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
312//!         fmt::Debug::fmt(self.0, f)
313//!     }
314//! }
315//!
316//! #[derive(Encode, Decode)]
317//! #[musli(name_type = CustomTag)]
318//! struct Struct {
319//!     #[musli(name = CustomTag(b"name in bytes"))]
320//!     name: String,
321//! }
322//!
323//! #[derive(Encode, Decode)]
324//! #[musli(name_type = CustomTag)]
325//! enum EnumWithCustomTag {
326//!     #[musli(name = CustomTag(b"variant one"))]
327//!     Variant1 {
328//!         /* .. */
329//!     },
330//! }
331//! ```
332//!
333//! <br>
334//!
335//! #### `#[musli(name_method = ..)]`
336//!
337//! This allows for explicitly setting which method should be used to decode
338//! names. Available options are:
339//!
340//! * `"value"` (default) - the name is decoded as a value.
341//! * `"unsized"` - the name is decoded as an unsized value, this is the default
342//!   if for example `#[musli(name_type = str)]` is used.
343//! * `"unsized_bytes"` - the name is decoded as a unsized bytes, this is the
344//!   default if for example `#[musli(name_type = [u8])]` is used.
345//!
346//! This can be overrided for values which are unsized, but cannot be determined
347//! through heuristics. Such a type must also implement [`Decode`] (for
348//! `"value"`), `DecodeUnsized`, or `DecodeUnsizedBytes` as appropriate.
349//!
350//! <br>
351//!
352//! #### `#[musli(bound = {..})]` and `#[musli(decode_bound = {..})]`
353//!
354//! These attributes can be used to apply bounds to an [`Encode`] or [`Decode`]
355//! implementation.
356//!
357//! These are necessary to use when a generic container is used to ensure that
358//! the given parameter implements the necessary bounds.
359//!
360//! `#[musli(bound = {..})]` applies to all implementations while
361//! `#[musli(decode_bound = {..})]` only applies to the [`Decode`]
362//! implementation. The latter allows for using the decode lifetime parameter
363//! (which defaults to `'de`).
364//!
365//! ```
366//! use musli::{Decode, Encode};
367//! use musli::mode::{Binary, Text};
368//!
369//! #[derive(Clone, Debug, PartialEq, Encode, Decode)]
370//! #[musli(mode = Binary, bound = {T: Encode<Binary>}, decode_bound = {T: Decode<'de, Binary>})]
371//! #[musli(mode = Text, bound = {T: Encode<Text>}, decode_bound = {T: Decode<'de, Text>})]
372//! pub struct GenericWithBound<T> {
373//!     value: T,
374//! }
375//! ```
376//!
377//! <br>
378//!
379//! ## Enum attributes
380//!
381//! <br>
382//!
383//! #### `#[musli(tag = ..)]`
384//!
385//! This attribute causes the enum to be internally tagged, with the given tag.
386//! See [enum representations](#enum-representations) for details on this
387//! representation.
388//!
389//! ```
390//! # use musli::{Encode, Decode};
391//! # #[derive(Encode, Decode)] struct Params;
392//! # #[derive(Encode, Decode)] struct Value;
393//! #[derive(Encode, Decode)]
394//! #[musli(name_all = "name", tag = "type")]
395//! enum Message {
396//!     Request { id: String, method: String, params: Params },
397//!     Response { id: String, result: Value },
398//! }
399//! ```
400//!
401//! <br>
402//!
403//! ## Variant attributes
404//!
405//! *Variant attributes* are attributes which apply to each individual variant
406//! in an `enum`. Like the use of `#[musli(name = ..)]` here:
407//!
408//! ```
409//! use musli::{Encode, Decode};
410//!
411//! #[derive(Encode, Decode)]
412//!#[musli(name_all = "name")]
413//! enum Enum {
414//!     Variant {
415//!         /* variant body */
416//!     },
417//!     #[musli(name = "Other")]
418//!     Something {
419//!         /* variant body */
420//!     },
421//! }
422//! ```
423//!
424//! <br>
425//!
426//! #### `#[musli(name = ..)]`
427//!
428//! This allows for renaming a variant from its default value. It can take any
429//! value (including complex ones) that can be serialized with the current
430//! encoding, such as:
431//!
432//! * `#[musli(name = 1)]`
433//! * `#[musli(name = "Hello World")]`
434//! * `#[musli(name = b"box\0")]`
435//! * `#[musli(name = SomeStruct { field: 42 })]` (if `SomeStruct` implements
436//!   [`Encode`] and [`Decode`] as appropriate).
437//!
438//! If the type of the tag is ambiguous it can be explicitly specified through
439//! the `#[musli(name_type)]` attribute.
440//!
441//! <br>
442//!
443//! #### `#[musli(pattern = ..)]`
444//!
445//! A pattern to match for decoding a variant.
446//!
447//! This allows for more flexibility when decoding variants.
448//!
449//! ```
450//! use musli::{Encode, Decode};
451//!
452//! #[derive(Encode, Decode)]
453//! enum Enum {
454//!     Variant1,
455//!     Variant2,
456//!     #[musli(mode = Binary, pattern = 2..=4)]
457//!     Deprecated,
458//! }
459//! ```
460//!
461//! <br>
462//!
463//! #### `#[musli(name_all = "..")]`
464//!
465//! Allos for renaming every field in the variant. It can take any of the
466//! following values:
467//!
468//! * `index` (default) - the index of the field will be used.
469//! * `name` - the literal name of the field will be used.
470//! * `PascalCase` - the field will be converted to pascal case.
471//! * `camelCase` - the field will be converted to camel case.
472//! * `snake_case` - the field will be converted to snake case.
473//! * `SCREAMING_SNAKE_CASE` - the field will be converted to screaming snake case.
474//! * `kebab-case` - the field will be converted to kebab case.
475//! * `SCREAMING-KEBAB-CASE` - the field will be converted to screaming kebab case.
476//!
477//! ```
478//! use musli::{Encode, Decode};
479//!
480//! #[derive(Encode, Decode)]
481//! enum PascalCaseEnum {
482//!     #[musli(name_all = "PascalCase")]
483//!     Variant {
484//!         field_name: u32,
485//!     }
486//! }
487//!
488//! #[derive(Encode, Decode)]
489//! enum NamedEnum {
490//!     #[musli(name_all = "name")]
491//!     Variant {
492//!         field1: u32,
493//!     },
494//!     Variant2 {
495//!         field1: u32,
496//!     },
497//! }
498//! ```
499//!
500//! <br>
501//!
502//! #### `#[musli(name_type = ..)]`
503//!
504//! This indicates which type any contained `#[musli(tag = ..)]` attributes
505//! should have. Tags can usually be inferred, but specifying this field ensures
506//! that all tags have a well-defined type.
507//!
508//! The following values are treated specially:
509//! * `str` applies `#[musli(name_all = "name")]` by default.
510//! * `[u8]` applies `#[musli(name_all = "name")]` by default.
511//!
512//! ```
513//! use core::fmt;
514//!
515//! use musli::{Encode, Decode};
516//!
517//! #[derive(Debug, PartialEq, Eq, Encode, Decode)]
518//! #[musli(transparent)]
519//! struct CustomTag<'a>(&'a [u8]);
520//!
521//! impl fmt::Display for CustomTag<'_> {
522//!     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
523//!         fmt::Debug::fmt(self.0, f)
524//!     }
525//! }
526//!
527//! #[derive(Encode, Decode)]
528//! #[musli(name_type = usize)]
529//! enum Enum {
530//!     #[musli(name = 0usize, name_type = CustomTag)]
531//!     Variant {
532//!         #[musli(name = CustomTag(b"field1"))]
533//!         field1: u32,
534//!         #[musli(name = CustomTag(b"field2"))]
535//!         field2: u32,
536//!     },
537//!     #[musli(name = 1usize, name_all = "name")]
538//!     Variant2 {
539//!         #[musli(name = "field1")]
540//!         field1: u32,
541//!         #[musli(name = "field2")]
542//!         field2: u32,
543//!     },
544//! }
545//! ```
546//!
547//! <br>
548//!
549//! #### `#[musli(name_method = ..)]`
550//!
551//! This allows for explicitly setting which method should be used to decode
552//! field names. Available options are:
553//!
554//! * `"value"` (default) - the name is decoded as a value.
555//! * `"unsized"` - the name is decoded as an unsized value, this is the default
556//!   if for example `#[musli(name_type = str)]` is used.
557//! * `"unsized_bytes"` - the name is decoded as a unsized bytes, this is the
558//!   default if for example `#[musli(name_type = [u8])]` is used.
559//!
560//! This can be overrided for values which are unsized, but cannot be determined
561//! through heuristics. Such a type must also implement [`Decode`] (for
562//! `"value"`), `DecodeUnsized`, or `DecodeUnsizedBytes` as appropriate.
563//!
564//! <br>
565//!
566//! #### `#[musli(transparent)]`
567//!
568//! This can only be used on variants which have a single field. It will cause
569//! that field to define how that variant is encoded or decoded transparently
570//! without being treated as a field.
571//!
572//! <br>
573//!
574//! #### `#[musli(default)]`
575//!
576//! This defines the variant that will be used in case no other variant matches.
577//! Only one such variant can be defined.
578//!
579//! ```
580//! use musli::{Encode, Decode};
581//!
582//! #[derive(Debug, PartialEq, Eq, Encode, Decode)]
583//! #[musli(name_all = "kebab-case")]
584//! enum Animal {
585//!     Cat,
586//!     Dog,
587//!     #[musli(default)]
588//!     Unknown,
589//! }
590//! ```
591//!
592//! <br>
593//!
594//! ## Field attributes
595//!
596//! *Field attributes* are attributes which apply to each individual field
597//! either in a `struct` or an `enum` variant. Like the uses of `#[musli(all)]`
598//! here:
599//!
600//! ```
601//! use musli::{Encode, Decode};
602//!
603//! #[derive(Encode, Decode)]
604//! #[musli(name_all = "name")]
605//! struct Struct {
606//!     #[musli(name = "other")]
607//!     something: String,
608//!     #[musli(skip, default = default_field)]
609//!     skipped_field: u32,
610//! }
611//!
612//! fn default_field() -> u32 {
613//!     42
614//! }
615//!
616//! #[derive(Encode, Decode)]
617//! #[musli(name_all = "name")]
618//! enum Enum {
619//!     #[musli(name_all = "name")]
620//!     Variant {
621//!         #[musli(name = "other")]
622//!         something: String,
623//!     }
624//! }
625//! ```
626//!
627//! <br>
628//!
629//! #### `#[musli(skip)]`
630//!
631//! This attribute means that the entire field is skipped. If a field is decoded
632//! it uses [`Default::default`] to construct the value. Other defaults can be
633//! specified with [`#[musli(default = <path>)]`][#muslidefault--path].
634//!
635//! ```
636//! use musli::{Encode, Decode};
637//!
638//! #[derive(Encode, Decode)]
639//! struct Person {
640//!     name: String,
641//!     #[musli(skip)]
642//!     age: Option<u32>,
643//!     #[musli(skip, default = default_country)]
644//!     country: Option<String>,
645//! }
646//!
647//! fn default_country() -> Option<String> {
648//!     Some(String::from("Earth"))
649//! }
650//! ```
651//!
652//! <br>
653//!
654//! #### `#[musli(default [= <path>])]`
655//!
656//! When a field is absent or disabled with `#[musli(skip)]`, this attribute
657//! specifies that a default value should be used instead.
658//!
659//! If `#[musli(default)]` is specified, the default value is constructed using
660//! [`Default::default`].
661//!
662//! If `#[musli(default = <path>)]` is specified, the default value is
663//! constructed by calling the function at `<path>`.
664//!
665//! ```
666//! use musli::{Encode, Decode};
667//!
668//! #[derive(Encode, Decode)]
669//! struct Person {
670//!     name: String,
671//!     #[musli(default)]
672//!     age: Option<u32>,
673//!     #[musli(default = default_height)]
674//!     height: Option<u32>,
675//!     #[musli(skip, default = default_meaning)]
676//!     meaning: u32,
677//! }
678//!
679//! fn default_height() -> Option<u32> {
680//!     Some(180)
681//! }
682//!
683//! fn default_meaning() -> u32 {
684//!     42
685//! }
686//! ```
687//!
688//! <br>
689//!
690//! #### `#[musli(name = ..)]`
691//!
692//! This allows for renaming a field from its default value. It can take any
693//! value (including complex ones) that can be serialized with the current
694//! encoding, such as:
695//!
696//! * `#[musli(name = 1)]`
697//! * `#[musli(name = "Hello World")]`
698//! * `#[musli(name = b"box\0")]`
699//! * `#[musli(name = SomeStruct { field: 42 })]` (if `SomeStruct` implements
700//!   [`Encode`] and [`Decode`] as appropriate).
701//!
702//! If the type of the tag is ambiguous it can be explicitly specified through
703//! the `#[musli(name_type)]` variant or container attributes.
704//!
705//! <br>
706//!
707//! #### `#[musli(pattern = ..)]`
708//!
709//! A pattern to match for decoding the given field.
710//!
711//! This allows for more flexibility when decoding fields.
712//!
713//! ```
714//! use musli::{Encode, Decode};
715//!
716//! #[derive(Encode, Decode)]
717//! struct Struct {
718//!     field1: u32,
719//!     field2: u32,
720//!     #[musli(mode = Binary, pattern = 2..=4)]
721//!     other: u32,
722//! }
723//! ```
724//!
725//! <br>
726//!
727//! #### `#[musli(packed)]`
728//!
729//! This specifies that encoding and decoding should happen through the
730//! [`EncodePacked`] and [`DecodePacked`] traits, instead of the default
731//! [`Encode`] and [`Decode`].
732//!
733//! These traits contained implementations which are biased towards encoding the
734//! field as a compact, non-future compatible pack. In essense, the fields are
735//! encoded "one after another" without any metadata separating them. So for
736//! packed fields, the order, types and number of the fields are important.
737//!
738//! ```
739//! use std::collections::VecDeque;
740//!
741//! use musli::{Decode, Encode};
742//!
743//! #[derive(Decode, Encode)]
744//! struct Container {
745//!     #[musli(packed)]
746//!     tuple: (u32, u64),
747//!     #[musli(packed)]
748//!     array: [u32; 4],
749//! }
750//! ```
751//!
752//! <br>
753//!
754//! #### `#[musli(bytes)]`
755//!
756//! This specifies that encoding and decoding should happen through the
757//! [`EncodeBytes`] and [`DecodeBytes`] traits, instead of the default
758//! [`Encode`] and [`Decode`].
759//!
760//! These traits contained implementations which are biased towards encoding the
761//! field as an array of bytes.
762//!
763//! ```
764//! use std::collections::VecDeque;
765//!
766//! use musli::{Decode, Encode};
767//!
768//! #[derive(Decode, Encode)]
769//! struct Container<'de> {
770//!     #[musli(bytes)]
771//!     vec: Vec<u8>,
772//!     #[musli(bytes)]
773//!     vec_deque: VecDeque<u8>,
774//!     #[musli(bytes)]
775//!     bytes: &'de [u8],
776//! }
777//! ```
778//!
779//! <br>
780//!
781//! #### `#[musli(with = <path>)]`
782//!
783//! This specifies the path to a module to use instead of the fields default
784//! [`Encode`] or [`Decode`] implementations.
785//!
786//! It expects `encode` and `decode` and decodee function to be defined in the path being specified, like this:
787//!
788//! ```
789//! # mod example {
790//! use musli::{Decode, Encode};
791//!
792//! #[derive(Decode, Encode)]
793//! struct Container {
794//!     #[musli(with = self::module)]
795//!     field: Field,
796//! }
797//!
798//! struct Field {
799//!     /* internal */
800//! }
801//!
802//! mod module {
803//!     use musli::{Decoder, Encoder};
804//!
805//!     use super::Field;
806//!
807//!     pub fn encode<E>(field: &Field, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
808//!     where
809//!         E: Encoder,
810//! # { todo!() }
811//!
812//!     pub fn decode<'de, D>(cx: &D::Cx, decoder: D) -> Result<Field, D::Error>
813//!     where
814//!         D: Decoder<'de>,
815//! # { todo!() }
816//! }
817//! # }
818//! ```
819//!
820//! This can also be generic such as:
821//!
822//! ```
823//! # mod example {
824//! use musli::{Decode, Encode};
825//!
826//! #[derive(Decode, Encode)]
827//! struct Container {
828//!     #[musli(with = self::module)]
829//!     field: Field<u32>,
830//! }
831//!
832//! struct Field<T> {
833//!     /* internal */
834//! #   value: T,
835//! }
836//!
837//! mod module {
838//!     use musli::{Decoder, Encoder};
839//!
840//!     use super::Field;
841//!
842//!     pub fn encode<E, T>(field: &Field<T>, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
843//!     where
844//!         E: Encoder,
845//! # { todo!() }
846//!
847//!     pub fn decode<'de, D, T>(cx: &D::Cx, decoder: D) -> Result<Field<T>, D::Error>
848//!     where
849//!         D: Decoder<'de>,
850//! # { todo!() }
851//! }
852//! # }
853//! ```
854//!
855//! More complete example:
856//!
857//! ```
858//! # mod example {
859//! use std::collections::HashSet;
860//! use musli::{Encode, Decode};
861//!
862//! pub struct CustomUuid(u128);
863//!
864//! #[derive(Encode, Decode)]
865//! struct Struct {
866//!     #[musli(with = self::custom_uuid)]
867//!     id: CustomUuid,
868//!     #[musli(with = self::custom_set)]
869//!     numbers: HashSet<u32>,
870//! }
871//!
872//! mod custom_uuid {
873//!     use musli::{Context, Decode, Decoder, Encode, Encoder};
874//!
875//!     use super::CustomUuid;
876//!
877//!     pub fn encode<E>(uuid: &CustomUuid, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
878//!     where
879//!         E: Encoder,
880//!     {
881//!         uuid.0.encode(cx, encoder)
882//!     }
883//!
884//!     pub fn decode<'de, D>(cx: &D::Cx, decoder: D) -> Result<CustomUuid, D::Error>
885//!     where
886//!         D: Decoder<'de>,
887//!     {
888//!         Ok(CustomUuid(decoder.decode()?))
889//!     }
890//! }
891//!
892//! mod custom_set {
893//!     use std::collections::HashSet;
894//!     use std::hash::Hash;
895//!
896//!     use musli::{Context, Decode, Decoder, Encode, Encoder};
897//!
898//!     pub fn encode<E, T>(set: &HashSet<T>, cx: &E::Cx, encoder: E) -> Result<E::Ok, E::Error>
899//!     where
900//!         E: Encoder,
901//!         T: Encode<E::Mode> + Eq + Hash,
902//!     {
903//!         encoder.encode(set)
904//!     }
905//!
906//!     pub fn decode<'de, D, T>(cx: &D::Cx, decoder: D) -> Result<HashSet<T>, D::Error>
907//!     where
908//!         D: Decoder<'de>,
909//!         T: Decode<'de, D::Mode> + Eq + Hash,
910//!     {
911//!         decoder.decode()
912//!     }
913//! }
914//! # }
915//! ```
916//!
917//! <br>
918//!
919//! #### `#[musli(skip_encoding_if = <path>)]`
920//!
921//! This adds a condition to skip encoding a field entirely if the condition is
922//! true. This is very commonly used to skip over encoding `Option<T>` fields.
923//!
924//! ```
925//! use musli::{Encode, Decode};
926//!
927//! #[derive(Encode, Decode)]
928//! struct Person {
929//!     name: String,
930//!     #[musli(skip_encoding_if = Option::is_none)]
931//!     age: Option<u32>,
932//! }
933//! ```
934//!
935//! #### `#[musli(trace)]`
936//!
937//! This causes the field to use the [`DecodeTrace`] / [`EncodeTrace`] when
938//! encoding the field. This is left optional for types where enabling tracing
939//! for the field requires extra traits to be implemented, such as `HashMap<K,
940//! V>` where we'd need `K` to implement `fmt::Display`.
941//!
942//! Without using the `trace` attribute below, the keys in the `values` field
943//! would not be instrumented, so with a decoding error you'd see this:
944//!
945//! ```text
946//! .values: not numeric (at bytes 15-16)
947//! ```
948//!
949//! Instead of this (where `#[musli(trace)]` is enabled):
950//!
951//! ```text
952//! .values[Hello]: not numeric (at bytes 15-16)
953//! ```
954//!
955//! ```
956//! use std::collections::HashMap;
957//!
958//! use musli::{Encode, Decode};
959//!
960//! #[derive(Encode, Decode)]
961//! struct Collection {
962//!     #[musli(trace)]
963//!     values: HashMap<String, u32>,
964//! }
965//! ```
966//!
967//! <br>
968//!
969//! # Enum representations
970//!
971//! Müsli supports the following enum representations, which mimics the ones
972//! supported by *serde*:
973//!
974//! * Externally tagged (*default*).
975//! * Internally tagged when `#[musli(tag = ..)]` is specified on the enum.
976//! * Adjacently tagged when both `#[musli(tag = ..)]` and `#[musli(content)]`
977//!   are specified.
978//!
979//! <br>
980//!
981//! ## Externally tagged
982//!
983//! ```
984//! # use musli::{Encode, Decode};
985//! # #[derive(Encode, Decode)] struct Params;
986//! # #[derive(Encode, Decode)] struct Value;
987//! #[derive(Encode, Decode)]
988//! enum Message {
989//!     Request { id: String, method: String, params: Params },
990//!     Response { id: String, result: Value },
991//! }
992//! ```
993//!
994//! When an enum is externally tagged it is represented by a single field
995//! indicating the variant of the enum.
996//!
997//! ```json
998//! {"Request": {"id": "...", "method": "...", "params": {...}}}
999//! ```
1000//!
1001//! This is the most portable representation and is supported by most formats.
1002//! It has special support in the [`Encoder`] and [`Decoder`] traits through
1003//! [`Encoder::encode_variant`] and [`Decoder::decode_variant`].
1004//!
1005//! Conceptually this can be considered as a "pair", where the variant tag can
1006//! be extracted from the format before the variant is decoded.
1007//!
1008//! <br>
1009//!
1010//! ## Internally tagged
1011//!
1012//! ```
1013//! # use musli::{Encode, Decode};
1014//! # #[derive(Encode, Decode)] struct Params;
1015//! # #[derive(Encode, Decode)] struct Value;
1016//! #[derive(Encode, Decode)]
1017//! #[musli(name_all = "name", tag = "type")]
1018//! enum Message {
1019//!     Request { id: String, method: String, params: Params },
1020//!     Response { id: String, result: Value },
1021//! }
1022//! ```
1023//!
1024//! In JSON, the `Message::Request` would be represented as:
1025//!
1026//! ```json
1027//! {"type": "Request", "id": "...", "method": "...", "params": {...}}
1028//! ```
1029//!
1030//! This is only supported by formats which are *self descriptive*, which is a
1031//! requirement for the format to be buffered through [`Decoder::decode_buffer`].
1032//!
1033//! It is necessary to buffer the value, since we need to inspect the fields of
1034//! a map for the field corresponding to the `tag`, and then use this to
1035//! determine which decoder implementation to call.
1036//!
1037//! [`Binary`]: crate::mode::Binary
1038//! [`Text`]: crate::mode::Text
1039//! [`Decode`]: crate::Decode
1040//! [`DecodeBytes`]: crate::de::DecodeBytes
1041//! [`DecodePacked`]: crate::de::DecodePacked
1042//! [`Decoder::decode_buffer`]: crate::Decoder::decode_buffer
1043//! [`Decoder::decode_variant`]: crate::Decoder::decode_variant
1044//! [`Decoder`]: crate::Decoder
1045//! [`DecodeTrace`]: crate::de::DecodeTrace
1046//! [`Encode`]: crate::Encode
1047//! [`EncodeBytes`]: crate::en::EncodeBytes
1048//! [`EncodePacked`]: crate::en::EncodePacked
1049//! [`Encoder::encode_variant`]: crate::Encoder::encode_variant
1050//! [`Encoder`]: crate::Encoder
1051//! [`EncodeTrace`]: crate::en::EncodeTrace
1052//! [default mode]: crate::mode::Binary
1053
1054// Parts of this documentation