1#![doc=include_str!("../../doc/serdes/array.md")]
2
3use core::{
4 any,
5 fmt::{
6 self,
7 Formatter,
8 },
9};
10
11use serde::{
12 de::{
13 Deserialize,
14 Deserializer,
15 Error,
16 MapAccess,
17 SeqAccess,
18 Unexpected,
19 Visitor,
20 },
21 ser::{
22 Serialize,
23 SerializeStruct,
24 Serializer,
25 },
26};
27
28use super::{
29 utils::{
30 Array,
31 TypeName,
32 },
33 Field,
34 FIELDS,
35};
36use crate::{
37 array::BitArray,
38 index::BitIdx,
39 mem::bits_of,
40 order::BitOrder,
41 store::BitStore,
42};
43
44impl<T, O> Serialize for BitArray<T, O>
45where
46 T: BitStore,
47 O: BitOrder,
48 T::Mem: Serialize,
49{
50 #[inline]
51 fn serialize<S>(&self, serializer: S) -> super::Result<S>
52 where S: Serializer {
53 let mut state = serializer.serialize_struct("BitArr", FIELDS.len())?;
54
55 state.serialize_field("order", &any::type_name::<O>())?;
56 state.serialize_field("head", &BitIdx::<T::Mem>::MIN)?;
57 state.serialize_field("bits", &(self.len() as u64))?;
58 state.serialize_field(
59 "data",
60 Array::from_ref(core::array::from_ref(&self.data)),
61 )?;
62
63 state.end()
64 }
65}
66
67impl<T, O, const N: usize> Serialize for BitArray<[T; N], O>
68where
69 T: BitStore,
70 O: BitOrder,
71 T::Mem: Serialize,
72{
73 #[inline]
74 fn serialize<S>(&self, serializer: S) -> super::Result<S>
75 where S: Serializer {
76 let mut state = serializer.serialize_struct("BitArr", FIELDS.len())?;
77
78 state.serialize_field("order", &any::type_name::<O>())?;
79 state.serialize_field("head", &BitIdx::<T::Mem>::MIN)?;
80 state.serialize_field("bits", &(self.len() as u64))?;
81 state.serialize_field("data", Array::from_ref(&self.data))?;
82
83 state.end()
84 }
85}
86
87impl<'de, T, O> Deserialize<'de> for BitArray<T, O>
88where
89 T: BitStore,
90 O: BitOrder,
91 T::Mem: Deserialize<'de>,
92{
93 #[inline]
94 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95 where D: Deserializer<'de> {
96 deserializer
97 .deserialize_struct("BitArr", FIELDS, BitArrVisitor::<T, O, 1>::THIS)
98 .map(|BitArray { data: [elem], .. }| BitArray::new(elem))
99 }
100}
101
102impl<'de, T, O, const N: usize> Deserialize<'de> for BitArray<[T; N], O>
103where
104 T: BitStore,
105 O: BitOrder,
106 T::Mem: Deserialize<'de>,
107{
108 #[inline]
109 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
110 where D: Deserializer<'de> {
111 deserializer.deserialize_struct(
112 "BitArr",
113 FIELDS,
114 BitArrVisitor::<T, O, N>::THIS,
115 )
116 }
117}
118
119struct BitArrVisitor<T, O, const N: usize>
121where
122 T: BitStore,
123 O: BitOrder,
124{
125 order: Option<TypeName<O>>,
127 head: Option<BitIdx<T::Mem>>,
130 bits: Option<u64>,
132 data: Option<Array<T, N>>,
134}
135
136impl<'de, T, O, const N: usize> BitArrVisitor<T, O, N>
137where
138 T: BitStore,
139 O: BitOrder,
140 Array<T, N>: Deserialize<'de>,
141{
142 const THIS: Self = Self {
144 order: None,
145 head: None,
146 bits: None,
147 data: None,
148 };
149
150 #[inline]
152 fn assemble<E>(mut self) -> Result<BitArray<[T; N], O>, E>
153 where E: Error {
154 self.order.take().ok_or_else(|| E::missing_field("order"))?;
155 let head = self.head.take().ok_or_else(|| E::missing_field("head"))?;
156 let bits = self.bits.take().ok_or_else(|| E::missing_field("bits"))?;
157 let data = self.data.take().ok_or_else(|| E::missing_field("data"))?;
158
159 if head != BitIdx::MIN {
160 return Err(E::invalid_value(
161 Unexpected::Unsigned(head.into_inner() as u64),
162 &"`BitArray` must have a head-bit of `0`",
163 ));
164 }
165 let bits = bits as usize;
166 if bits != bits_of::<[T; N]>() {
167 return Err(E::invalid_length(bits, &self));
168 }
169
170 Ok(BitArray::new(data.inner))
171 }
172}
173
174impl<'de, T, O, const N: usize> Visitor<'de> for BitArrVisitor<T, O, N>
175where
176 T: BitStore,
177 O: BitOrder,
178 Array<T, N>: Deserialize<'de>,
179{
180 type Value = BitArray<[T; N], O>;
181
182 #[inline]
183 fn expecting(&self, fmt: &mut Formatter) -> fmt::Result {
184 write!(
185 fmt,
186 "a `BitArray<[u{}; {}], {}>`",
187 bits_of::<T::Mem>(),
188 N,
189 any::type_name::<O>(),
190 )
191 }
192
193 #[inline]
194 fn visit_seq<V>(mut self, mut seq: V) -> Result<Self::Value, V::Error>
195 where V: SeqAccess<'de> {
196 self.order = Some(
197 seq.next_element()?
198 .ok_or_else(|| <V::Error>::invalid_length(0, &self))?,
199 );
200 self.head = Some(
201 seq.next_element()?
202 .ok_or_else(|| <V::Error>::invalid_length(1, &self))?,
203 );
204 self.bits = Some(
205 seq.next_element()?
206 .ok_or_else(|| <V::Error>::invalid_length(2, &self))?,
207 );
208 self.data = Some(
209 seq.next_element()?
210 .ok_or_else(|| <V::Error>::invalid_length(3, &self))?,
211 );
212
213 self.assemble()
214 }
215
216 #[inline]
217 fn visit_map<V>(mut self, mut map: V) -> Result<Self::Value, V::Error>
218 where V: MapAccess<'de> {
219 while let Some(key) = map.next_key()? {
220 match key {
221 Field::Order => {
222 if self.order.replace(map.next_value()?).is_some() {
223 return Err(<V::Error>::duplicate_field("order"));
224 }
225 },
226 Field::Head => {
227 if self.head.replace(map.next_value()?).is_some() {
228 return Err(<V::Error>::duplicate_field("head"));
229 }
230 },
231 Field::Bits => {
232 if self.bits.replace(map.next_value()?).is_some() {
233 return Err(<V::Error>::duplicate_field("bits"));
234 }
235 },
236 Field::Data => {
237 if self.data.replace(map.next_value()?).is_some() {
238 return Err(<V::Error>::duplicate_field("data"));
239 }
240 },
241 }
242 }
243
244 self.assemble()
245 }
246}
247
248#[cfg(test)]
249mod tests {
250 #[cfg(all(feature = "alloc", not(feature = "std")))]
251 use alloc::format;
252 use core::any;
253
254 use serde_test::{
255 assert_de_tokens,
256 assert_de_tokens_error,
257 assert_ser_tokens,
258 Token,
259 };
260
261 use crate::prelude::*;
262
263 #[test]
264 #[cfg(feature = "std")]
265 fn roundtrip() -> Result<(), Box<dyn std::error::Error>> {
266 type BA = BitArr!(for 16, in u8, Msb0);
267 let array = [0x3Cu8, 0xA5].into_bitarray::<Msb0>();
268
269 let bytes = bincode::serialize(&array)?;
270 let array2 = bincode::deserialize::<BA>(&bytes)?;
271 assert_eq!(array, array2);
272
273 let json = serde_json::to_string(&array)?;
274 let array3 = serde_json::from_str::<BA>(&json)?;
275 assert_eq!(array, array3);
276
277 let json_value = serde_json::to_value(&array)?;
278 let array4 = serde_json::from_value::<BA>(json_value)?;
279 assert_eq!(array, array4);
280
281 type BA2 = BitArray<u16, Msb0>;
282 let array = BA2::new(44203);
283
284 let bytes = bincode::serialize(&array)?;
285 let array2 = bincode::deserialize::<BA2>(&bytes)?;
286 assert_eq!(array, array2);
287
288 let json = serde_json::to_string(&array)?;
289 let array3 = serde_json::from_str::<BA2>(&json)?;
290 assert_eq!(array, array3);
291
292 let json_value = serde_json::to_value(&array)?;
293 let array4 = serde_json::from_value::<BA2>(json_value)?;
294 assert_eq!(array, array4);
295
296 Ok(())
297 }
298
299 #[test]
300 fn tokens() {
301 let array = [0x3Cu8, 0xA5].into_bitarray::<Msb0>();
302 let tokens = &mut [
303 Token::Struct {
304 name: "BitArr",
305 len: 4,
306 },
307 Token::Str("order"),
308 Token::Str(any::type_name::<Msb0>()),
309 Token::Str("head"),
310 Token::Struct {
311 name: "BitIdx",
312 len: 2,
313 },
314 Token::Str("width"),
315 Token::U8(8),
316 Token::Str("index"),
317 Token::U8(0),
318 Token::StructEnd,
319 Token::Str("bits"),
320 Token::U64(16),
321 Token::Str("data"),
322 Token::Tuple { len: 2 },
323 Token::U8(0x3C),
324 Token::U8(0xA5),
325 Token::TupleEnd,
326 Token::StructEnd,
327 ];
328
329 assert_ser_tokens(&array, tokens);
330
331 tokens[1 .. 4].copy_from_slice(&[
332 Token::BorrowedStr("order"),
333 Token::BorrowedStr(any::type_name::<Msb0>()),
334 Token::BorrowedStr("head"),
335 ]);
336 tokens[5] = Token::BorrowedStr("width");
337 tokens[7] = Token::BorrowedStr("index");
338 tokens[10] = Token::BorrowedStr("bits");
339 tokens[12] = Token::BorrowedStr("data");
340 assert_de_tokens(&array, tokens);
341 }
342
343 #[test]
344 #[cfg(feature = "alloc")]
345 fn errors() {
346 type BA = BitArr!(for 8, in u8, Msb0);
347 let mut tokens = vec![
348 Token::Seq { len: Some(4) },
349 Token::BorrowedStr(any::type_name::<Msb0>()),
350 ];
351
352 assert_de_tokens_error::<BitArr!(for 8, in u8, Lsb0)>(
353 &tokens,
354 &format!(
355 "invalid value: string \"{}\", expected the string \"{}\"",
356 any::type_name::<Msb0>(),
357 any::type_name::<Lsb0>(),
358 ),
359 );
360
361 tokens.extend([
362 Token::Seq { len: Some(2) },
363 Token::U8(8),
364 Token::U8(0),
365 Token::SeqEnd,
366 Token::U64(8),
367 Token::Tuple { len: 1 },
368 Token::U8(0),
369 Token::TupleEnd,
370 Token::SeqEnd,
371 ]);
372
373 tokens[6] = Token::U64(7);
374 assert_de_tokens_error::<BA>(
375 &tokens,
376 "invalid length 7, expected a `BitArray<[u8; 1], \
377 bitvec::order::Msb0>`",
378 );
379
380 tokens[4] = Token::U8(1);
381 assert_de_tokens_error::<BA>(
382 &tokens,
383 "invalid value: integer `1`, expected `BitArray` must have a \
384 head-bit of `0`",
385 );
386
387 assert_de_tokens_error::<BA>(
388 &[
389 Token::Struct {
390 name: "BitArr",
391 len: 2,
392 },
393 Token::BorrowedStr("placeholder"),
394 ],
395 &format!(
396 "unknown field `placeholder`, expected one of `{}`",
397 super::FIELDS.join("`, `"),
398 ),
399 );
400 assert_de_tokens_error::<BA>(
401 &[
402 Token::Struct {
403 name: "BitArr",
404 len: 2,
405 },
406 Token::BorrowedStr("order"),
407 Token::BorrowedStr(any::type_name::<Msb0>()),
408 Token::BorrowedStr("order"),
409 Token::BorrowedStr(any::type_name::<Msb0>()),
410 Token::StructEnd,
411 ],
412 "duplicate field `order`",
413 );
414 assert_de_tokens_error::<BA>(
415 &[
416 Token::Struct {
417 name: "BitArr",
418 len: 2,
419 },
420 Token::BorrowedStr("head"),
421 Token::Seq { len: Some(2) },
422 Token::U8(8),
423 Token::U8(0),
424 Token::SeqEnd,
425 Token::BorrowedStr("head"),
426 Token::Seq { len: Some(2) },
427 Token::U8(8),
428 Token::U8(0),
429 Token::SeqEnd,
430 Token::StructEnd,
431 ],
432 "duplicate field `head`",
433 );
434 assert_de_tokens_error::<BA>(
435 &[
436 Token::Struct {
437 name: "BitArr",
438 len: 2,
439 },
440 Token::BorrowedStr("bits"),
441 Token::U64(8),
442 Token::BorrowedStr("bits"),
443 Token::U64(8),
444 Token::StructEnd,
445 ],
446 "duplicate field `bits`",
447 );
448 assert_de_tokens_error::<BA>(
449 &[
450 Token::Struct {
451 name: "BitArr",
452 len: 2,
453 },
454 Token::BorrowedStr("data"),
455 Token::Tuple { len: 1 },
456 Token::U8(0),
457 Token::TupleEnd,
458 Token::BorrowedStr("data"),
459 Token::Tuple { len: 1 },
460 Token::U8(1),
461 Token::TupleEnd,
462 Token::StructEnd,
463 ],
464 "duplicate field `data`",
465 );
466 }
467}