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}