musli_core/en/encode.rs
1use crate::en::Encoder;
2
3/// Trait governing how types are encoded.
4///
5/// This is typically implemented automatically using the [`Encode` derive].
6///
7/// [`Encode` derive]: https://docs.rs/musli/latest/musli/_help/derives/
8///
9/// # Examples
10///
11/// ```
12/// use musli::Encode;
13///
14/// #[derive(Encode)]
15/// struct MyType {
16/// data: [u32; 8],
17/// }
18/// ```
19///
20/// Implementing manually:
21///
22/// ```
23/// use musli::{Encode, Encoder};
24///
25/// struct MyType {
26/// data: [u32; 8],
27/// }
28///
29/// impl<M> Encode<M> for MyType {
30/// type Encode = Self;
31///
32/// #[inline]
33/// fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
34/// where
35/// E: Encoder<Mode = M>,
36/// {
37/// encoder.encode(&self.data)
38/// }
39///
40/// #[inline]
41/// fn as_encode(&self) -> &Self::Encode {
42/// self
43/// }
44/// }
45/// ```
46pub trait Encode<M> {
47 /// Whether the type is packed. Packed types can be bitwise copied if the
48 /// representation of the serialization format is identical to the memory
49 /// layout of the type.
50 ///
51 /// Note that setting this to `true` has safety implications, since it
52 /// implies that assuming the type is correctly aligned it can be validly
53 /// bitwise copied when encoded. Setting it to `false` is always safe.
54 ///
55 /// This being set to `true` also implies that the type is `Copy`, and must
56 /// not have a `Drop` implementation.
57 const IS_BITWISE_ENCODE: bool = false;
58
59 /// The underlying type being encoded.
60 ///
61 /// This is used to "peek through" types like references being encoded.
62 type Encode: ?Sized + Encode<M>;
63
64 /// Encode the given output.
65 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
66 where
67 E: Encoder<Mode = M>;
68
69 /// The number of fields in the type.
70 #[inline]
71 fn size_hint(&self) -> Option<usize> {
72 None
73 }
74
75 /// Coerce into the underlying value being encoded.
76 fn as_encode(&self) -> &Self::Encode;
77}
78
79impl<T, M> Encode<M> for &T
80where
81 T: ?Sized + Encode<M>,
82{
83 type Encode = T;
84
85 const IS_BITWISE_ENCODE: bool = false;
86
87 #[inline]
88 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
89 where
90 E: Encoder<Mode = M>,
91 {
92 (**self).encode(encoder)
93 }
94
95 #[inline]
96 fn size_hint(&self) -> Option<usize> {
97 (**self).size_hint()
98 }
99
100 #[inline]
101 fn as_encode(&self) -> &Self::Encode {
102 self
103 }
104}
105
106impl<T, M> Encode<M> for &mut T
107where
108 T: ?Sized + Encode<M>,
109{
110 type Encode = T;
111
112 const IS_BITWISE_ENCODE: bool = false;
113
114 #[inline]
115 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
116 where
117 E: Encoder<Mode = M>,
118 {
119 (**self).encode(encoder)
120 }
121
122 #[inline]
123 fn size_hint(&self) -> Option<usize> {
124 (**self).size_hint()
125 }
126
127 #[inline]
128 fn as_encode(&self) -> &Self::Encode {
129 self
130 }
131}