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}