1use std::{
2 borrow::Cow,
3 collections::{BTreeMap, BTreeSet, HashMap, HashSet, LinkedList, VecDeque},
4 hash::Hash,
5 rc::Rc,
6 sync::Arc,
7};
8
9use bitvec::{order::Msb0, slice::BitSlice};
10use either::Either;
11
12use crate::{
13 Context, Error, StringError,
14 r#as::{AsWrap, Same},
15 de::BitUnpack,
16};
17
18use super::{BitReader, BitReaderExt};
19
20pub trait BitUnpackAs<'de, T> {
26 type Args;
27
28 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<T, R::Error>
30 where
31 R: BitReader<'de> + ?Sized;
32}
33#[inline]
35pub fn unpack_as<'de, T, As>(
36 mut bits: &'de BitSlice<u8, Msb0>,
37 args: As::Args,
38) -> Result<T, StringError>
39where
40 As: BitUnpackAs<'de, T>,
41{
42 bits.unpack_as::<_, As>(args)
43}
44
45#[inline]
47pub fn unpack_bytes_as<'de, T, As>(bytes: &'de [u8], args: As::Args) -> Result<T, StringError>
48where
49 As: BitUnpackAs<'de, T>,
50{
51 unpack_as::<_, As>(BitSlice::from_slice(bytes), args)
52}
53
54#[inline]
57pub fn unpack_fully_as<'de, T, As>(
58 mut bits: &'de BitSlice<u8, Msb0>,
59 args: As::Args,
60) -> Result<T, StringError>
61where
62 As: BitUnpackAs<'de, T>,
63{
64 let v = bits.unpack_as::<T, As>(args)?;
65 if !bits.is_empty() {
66 return Err(Error::custom("more data left"));
67 }
68 Ok(v)
69}
70
71#[inline]
74pub fn unpack_bytes_fully_as<'de, T, As>(bytes: &'de [u8], args: As::Args) -> Result<T, StringError>
75where
76 As: BitUnpackAs<'de, T>,
77{
78 unpack_fully_as::<_, As>(BitSlice::from_slice(bytes), args)
79}
80
81impl<'de, T, As, const N: usize> BitUnpackAs<'de, [T; N]> for [As; N]
82where
83 As: BitUnpackAs<'de, T>,
84 As::Args: Clone,
85{
86 type Args = As::Args;
87
88 #[inline]
89 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<[T; N], R::Error>
90 where
91 R: BitReader<'de> + ?Sized,
92 {
93 array_util::try_from_fn(|i| {
95 As::unpack_as(reader, args.clone()).with_context(|| format!("[{i}]"))
96 })
97 }
98}
99
100macro_rules! impl_bit_unpack_as_for_tuple {
101 ($($ts:ident as $as:ident:$ns:tt),*) => {
102 impl<'de, $($ts, $as),*> BitUnpackAs<'de, ($($ts,)*)> for ($($as,)*)
103 where $(
104 $as: BitUnpackAs<'de, $ts>,
105 )*
106 {
107 type Args = ($($as::Args,)*);
108
109 #[inline]
110 #[allow(unused_variables)]
111 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<($($ts,)*), R::Error>
112 where
113 R: BitReader<'de> + ?Sized,
114 {
115 Ok(($(
116 $as::unpack_as(reader, args.$ns)
117 .context(concat!(".", stringify!($ns)))?,
118 )*))
119 }
120 }
121 };
122}
123impl_bit_unpack_as_for_tuple!();
124impl_bit_unpack_as_for_tuple!(T0 as As0:0);
125impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1);
126impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2);
127impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3);
128impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3,T4 as As4:4);
129impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3,T4 as As4:4,T5 as As5:5);
130impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3,T4 as As4:4,T5 as As5:5,T6 as As6:6);
131impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3,T4 as As4:4,T5 as As5:5,T6 as As6:6,T7 as As7:7);
132impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3,T4 as As4:4,T5 as As5:5,T6 as As6:6,T7 as As7:7,T8 as As8:8);
133impl_bit_unpack_as_for_tuple!(T0 as As0:0,T1 as As1:1,T2 as As2:2,T3 as As3:3,T4 as As4:4,T5 as As5:5,T6 as As6:6,T7 as As7:7,T8 as As8:8,T9 as As9:9);
134
135impl<'de, T, As> BitUnpackAs<'de, Box<T>> for Box<As>
136where
137 As: BitUnpackAs<'de, T> + ?Sized,
138{
139 type Args = As::Args;
140
141 #[inline]
142 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Box<T>, R::Error>
143 where
144 R: BitReader<'de> + ?Sized,
145 {
146 AsWrap::<T, As>::unpack(reader, args)
147 .map(AsWrap::into_inner)
148 .map(Into::into)
149 }
150}
151
152impl<'de, T, As> BitUnpackAs<'de, Rc<T>> for Rc<As>
153where
154 As: BitUnpackAs<'de, T> + ?Sized,
155{
156 type Args = As::Args;
157
158 #[inline]
159 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Rc<T>, R::Error>
160 where
161 R: BitReader<'de> + ?Sized,
162 {
163 AsWrap::<T, As>::unpack(reader, args)
164 .map(AsWrap::into_inner)
165 .map(Into::into)
166 }
167}
168
169impl<'de, T, As> BitUnpackAs<'de, Arc<T>> for Arc<As>
170where
171 As: BitUnpackAs<'de, T> + ?Sized,
172{
173 type Args = As::Args;
174
175 #[inline]
176 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Arc<T>, R::Error>
177 where
178 R: BitReader<'de> + ?Sized,
179 {
180 AsWrap::<T, As>::unpack(reader, args)
181 .map(AsWrap::into_inner)
182 .map(Into::into)
183 }
184}
185
186impl<'de, 'a, T, As> BitUnpackAs<'de, Cow<'a, T>> for Cow<'a, As>
188where
189 T: ToOwned + ?Sized,
190 As: ToOwned + ?Sized,
191 As::Owned: BitUnpackAs<'de, T::Owned>,
192{
193 type Args = <As::Owned as BitUnpackAs<'de, T::Owned>>::Args;
194
195 #[inline]
196 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Cow<'a, T>, R::Error>
197 where
198 R: BitReader<'de> + ?Sized,
199 {
200 AsWrap::<T::Owned, As::Owned>::unpack(reader, args)
201 .map(AsWrap::into_inner)
202 .map(Cow::Owned)
203 }
204}
205impl<'de, Left, Right, AsLeft, AsRight> BitUnpackAs<'de, Either<Left, Right>>
211 for Either<AsLeft, AsRight>
212where
213 AsLeft: BitUnpackAs<'de, Left>,
214 AsRight: BitUnpackAs<'de, Right>,
215{
216 type Args = (AsLeft::Args, AsRight::Args);
217
218 #[inline]
219 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Either<Left, Right>, R::Error>
220 where
221 R: BitReader<'de> + ?Sized,
222 {
223 Ok(
224 Either::<AsWrap<Left, AsLeft>, AsWrap<Right, AsRight>>::unpack(reader, args)?
225 .map_either(AsWrap::into_inner, AsWrap::into_inner),
226 )
227 }
228}
229
230impl<'de, T, As> BitUnpackAs<'de, Option<T>> for Either<(), As>
231where
232 As: BitUnpackAs<'de, T>,
233{
234 type Args = As::Args;
235
236 #[inline]
237 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Option<T>, R::Error>
238 where
239 R: BitReader<'de> + ?Sized,
240 {
241 Ok(reader
242 .unpack_as::<Either<(), T>, Either<Same, As>>(((), args))?
243 .right())
244 }
245}
246
247impl<'de, T, As> BitUnpackAs<'de, Option<T>> for Option<As>
253where
254 As: BitUnpackAs<'de, T>,
255{
256 type Args = As::Args;
257
258 #[inline]
259 fn unpack_as<R>(reader: &mut R, args: Self::Args) -> Result<Option<T>, R::Error>
260 where
261 R: BitReader<'de> + ?Sized,
262 {
263 Ok(Option::<AsWrap<T, As>>::unpack(reader, args)?.map(AsWrap::into_inner))
264 }
265}
266
267impl<'de, T, As> BitUnpackAs<'de, Vec<T>> for Vec<As>
268where
269 As: BitUnpackAs<'de, T>,
270 As::Args: Clone,
271{
272 type Args = (usize, As::Args);
274
275 #[inline]
276 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<Vec<T>, R::Error>
277 where
278 R: BitReader<'de> + ?Sized,
279 {
280 reader.unpack_iter_as::<_, As>(args).take(len).collect()
281 }
282}
283
284impl<'de, T, As> BitUnpackAs<'de, VecDeque<T>> for VecDeque<As>
285where
286 As: BitUnpackAs<'de, T>,
287 As::Args: Clone,
288{
289 type Args = (usize, As::Args);
291
292 #[inline]
293 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<VecDeque<T>, R::Error>
294 where
295 R: BitReader<'de> + ?Sized,
296 {
297 reader.unpack_iter_as::<_, As>(args).take(len).collect()
298 }
299}
300
301impl<'de, T, As> BitUnpackAs<'de, LinkedList<T>> for LinkedList<As>
302where
303 As: BitUnpackAs<'de, T>,
304 As::Args: Clone,
305{
306 type Args = (usize, As::Args);
308
309 #[inline]
310 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<LinkedList<T>, R::Error>
311 where
312 R: BitReader<'de> + ?Sized,
313 {
314 reader.unpack_iter_as::<_, As>(args).take(len).collect()
315 }
316}
317
318impl<'de, T, As> BitUnpackAs<'de, BTreeSet<T>> for BTreeSet<As>
319where
320 T: Ord + Eq,
321 As: BitUnpackAs<'de, T>,
322 As::Args: Clone,
323{
324 type Args = (usize, As::Args);
326
327 #[inline]
328 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<BTreeSet<T>, R::Error>
329 where
330 R: BitReader<'de> + ?Sized,
331 {
332 reader.unpack_iter_as::<_, As>(args).take(len).collect()
333 }
334}
335
336impl<'de, K, V, KAs, VAs> BitUnpackAs<'de, BTreeMap<K, V>> for BTreeMap<KAs, VAs>
337where
338 K: Ord + Eq,
339 KAs: BitUnpackAs<'de, K>,
340 KAs::Args: Clone,
341 VAs: BitUnpackAs<'de, V>,
342 VAs::Args: Clone,
343{
344 type Args = (usize, (KAs::Args, VAs::Args));
346
347 #[inline]
348 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<BTreeMap<K, V>, R::Error>
349 where
350 R: BitReader<'de> + ?Sized,
351 {
352 reader
353 .unpack_iter_as::<_, (KAs, VAs)>(args)
354 .take(len)
355 .collect()
356 }
357}
358
359impl<'de, T, As> BitUnpackAs<'de, HashSet<T>> for HashSet<As>
360where
361 T: Hash + Eq,
362 As: BitUnpackAs<'de, T>,
363 As::Args: Clone,
364{
365 type Args = (usize, As::Args);
367
368 #[inline]
369 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<HashSet<T>, R::Error>
370 where
371 R: BitReader<'de> + ?Sized,
372 {
373 reader.unpack_iter_as::<_, As>(args).take(len).collect()
374 }
375}
376
377impl<'de, K, V, KAs, VAs> BitUnpackAs<'de, HashMap<K, V>> for HashMap<KAs, VAs>
378where
379 K: Hash + Eq,
380 KAs: BitUnpackAs<'de, K>,
381 KAs::Args: Clone,
382 VAs: BitUnpackAs<'de, V>,
383 VAs::Args: Clone,
384{
385 type Args = (usize, (KAs::Args, VAs::Args));
387
388 #[inline]
389 fn unpack_as<R>(reader: &mut R, (len, args): Self::Args) -> Result<HashMap<K, V>, R::Error>
390 where
391 R: BitReader<'de> + ?Sized,
392 {
393 reader
394 .unpack_iter_as::<_, (KAs, VAs)>(args)
395 .take(len)
396 .collect()
397 }
398}