1use core::fmt;
2
3use core::marker::PhantomData;
4
5use serde::{Deserializer, Serializer};
6
7use crate::encoding::Encoding;
8use crate::low_level;
9
10pub struct ArrayLike<Enc: Encoding>(PhantomData<Enc>);
26
27impl<Enc: Encoding> ArrayLike<Enc> {
28 pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
30 where
31 T: AsRef<[u8]>,
32 S: Serializer,
33 {
34 low_level::serialize_slice::<Enc, _>(obj.as_ref(), serializer)
35 }
36
37 pub fn deserialize<'de, T, E, D, const N: usize>(deserializer: D) -> Result<T, D::Error>
39 where
40 D: Deserializer<'de>,
41 T: TryFrom<[u8; N], Error = E>,
42 E: fmt::Display,
43 {
44 low_level::deserialize_array::<Enc, N, _, _, _>(deserializer)
45 }
46}
47
48pub struct SliceLike<Enc: Encoding>(PhantomData<Enc>);
56
57impl<Enc: Encoding> SliceLike<Enc> {
58 pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
60 where
61 T: AsRef<[u8]>,
62 S: Serializer,
63 {
64 low_level::serialize_slice::<Enc, _>(obj.as_ref(), serializer)
65 }
66
67 pub fn deserialize<'de, T, E, D>(deserializer: D) -> Result<T, D::Error>
69 where
70 D: Deserializer<'de>,
71 T: for<'a> TryFrom<&'a [u8], Error = E>,
72 E: fmt::Display,
73 {
74 low_level::deserialize_slice::<Enc, _, _, _>(deserializer)
75 }
76}
77
78pub struct BorrowedSliceLike<Enc: Encoding>(PhantomData<Enc>);
89
90impl<Enc: Encoding> BorrowedSliceLike<Enc> {
91 pub fn serialize<T, S>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 T: AsRef<[u8]>,
95 S: Serializer,
96 {
97 low_level::serialize_slice::<Enc, _>(obj.as_ref(), serializer)
98 }
99
100 pub fn deserialize<'de, T, E, D>(deserializer: D) -> Result<T, D::Error>
102 where
103 D: Deserializer<'de>,
104 T: Clone,
105 for<'a> &'a T: TryFrom<&'a [u8], Error = E>,
106 E: fmt::Display,
107 {
108 low_level::deserialize_borrowed_slice::<Enc, _, _, _>(deserializer)
109 }
110}
111
112pub struct BoxedArrayLike<Enc: Encoding>(PhantomData<Enc>);
121
122impl<Enc: Encoding> BoxedArrayLike<Enc> {
123 pub fn serialize<T, S, const N: usize>(obj: &T, serializer: S) -> Result<S::Ok, S::Error>
125 where
126 T: AsRef<[u8; N]>,
127 S: Serializer,
128 {
129 low_level::serialize_slice::<Enc, _>(obj.as_ref(), serializer)
130 }
131
132 pub fn deserialize<'de, T, E, D, const N: usize>(deserializer: D) -> Result<T, D::Error>
134 where
135 D: Deserializer<'de>,
136 T: TryFrom<[u8; N], Error = E>,
137 E: fmt::Display,
138 {
139 low_level::deserialize_array::<Enc, N, _, _, _>(deserializer)
140 }
141}
142
143#[cfg(feature = "generic-array-014")]
153pub struct GenericArray014<Enc: Encoding>(PhantomData<Enc>);
154
155#[cfg(feature = "generic-array-014")]
156impl<Enc: Encoding> GenericArray014<Enc> {
157 pub fn serialize<L, S>(
159 obj: &generic_array_014::GenericArray<u8, L>,
160 serializer: S,
161 ) -> Result<S::Ok, S::Error>
162 where
163 L: generic_array_014::ArrayLength<u8>,
164 S: Serializer,
165 {
166 low_level::serialize_slice::<Enc, _>(obj.as_ref(), serializer)
167 }
168
169 pub fn deserialize<'de, L, D>(
171 deserializer: D,
172 ) -> Result<generic_array_014::GenericArray<u8, L>, D::Error>
173 where
174 D: Deserializer<'de>,
175 L: generic_array_014::ArrayLength<u8>,
176 {
177 low_level::deserialize_generic_array_014::<Enc, L, _>(deserializer)
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use alloc::{boxed::Box, vec::Vec};
184
185 use serde::{Deserialize, Serialize};
186
187 use crate::{encoding::Hex, ArrayLike, BoxedArrayLike, SliceLike};
188
189 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
190 struct FixedArrayStruct(#[serde(with = "ArrayLike::<Hex>")] [u8; 4]);
191
192 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
193 struct VectorStruct(#[serde(with = "SliceLike::<Hex>")] Vec<u8>);
194
195 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
196 struct BoxedArrayStruct(#[serde(with = "BoxedArrayLike::<Hex>")] Box<[u8; 4]>);
197
198 #[test]
199 fn roundtrip_array() {
200 let val = FixedArrayStruct([1, 2, 3, 4]);
201 let val_bytes = rmp_serde::to_vec(&val).unwrap();
202 let val_back = rmp_serde::from_slice::<FixedArrayStruct>(&val_bytes).unwrap();
203 assert_eq!(val, val_back);
204 }
205
206 #[test]
207 fn roundtrip_slice() {
208 let val = VectorStruct([1, 2, 3, 4].into());
209 let val_bytes = rmp_serde::to_vec(&val).unwrap();
210 let val_back = rmp_serde::from_slice::<VectorStruct>(&val_bytes).unwrap();
211 assert_eq!(val, val_back);
212 }
213
214 #[test]
215 fn roundtrip_boxed_array() {
216 let val = BoxedArrayStruct([1, 2, 3, 4].into());
217 let val_bytes = rmp_serde::to_vec(&val).unwrap();
218 let val_back = rmp_serde::from_slice::<BoxedArrayStruct>(&val_bytes).unwrap();
219 assert_eq!(val, val_back);
220 }
221}