musli_core/en/
encode_bytes.rs

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