bitvec/serdes/
slice.rs

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