1pub mod r#as;
2
3use std::{borrow::Cow, rc::Rc, sync::Arc};
4
5use bitvec::{order::Msb0, slice::BitSlice, vec::BitVec};
6use either::Either;
7
8use crate::{
9 Context,
10 r#as::{BorrowCow, FromInto, Same},
11};
12
13use super::{BitReader, BitReaderExt};
14
15pub trait BitUnpackWithArgs<'de>: Sized {
20 type Args;
21
22 fn unpack_with<R>(reader: R, args: Self::Args) -> Result<Self, R::Error>
24 where
25 R: BitReader<'de>;
26}
27
28impl<'de, T, const N: usize> BitUnpackWithArgs<'de> for [T; N]
29where
30 T: BitUnpackWithArgs<'de>,
31 T::Args: Clone,
32{
33 type Args = T::Args;
34
35 #[inline]
36 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
37 where
38 R: BitReader<'de>,
39 {
40 array_util::try_from_fn(|i| {
42 T::unpack_with(&mut reader, args.clone()).with_context(|| format!("[{i}]"))
43 })
44 }
45}
46
47macro_rules! impl_bit_unpack_with_args_for_tuple {
48 ($($n:tt:$t:ident),+) => {
49 impl<'de, $($t),+> BitUnpackWithArgs<'de> for ($($t,)+)
50 where $(
51 $t: BitUnpackWithArgs<'de>,
52 )+
53 {
54 type Args = ($($t::Args,)+);
55
56 #[inline]
57 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
58 where
59 R: BitReader<'de>,
60 {
61 Ok(($(
62 $t::unpack_with(&mut reader, args.$n).context(concat!(".", stringify!($n)))?,
63 )+))
64 }
65 }
66 };
67}
68impl_bit_unpack_with_args_for_tuple!(0:T0);
69impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1);
70impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2);
71impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3);
72impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4);
73impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5);
74impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6);
75impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7);
76impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7,8:T8);
77impl_bit_unpack_with_args_for_tuple!(0:T0,1:T1,2:T2,3:T3,4:T4,5:T5,6:T6,7:T7,8:T8,9:T9);
78
79impl<'de, T> BitUnpackWithArgs<'de> for Vec<T>
80where
81 T: BitUnpackWithArgs<'de>,
82 T::Args: Clone,
83{
84 type Args = (usize, T::Args);
86
87 #[inline]
88 fn unpack_with<R>(mut reader: R, (len, args): Self::Args) -> Result<Self, R::Error>
89 where
90 R: BitReader<'de>,
91 {
92 reader.unpack_iter_with(args).take(len).collect()
93 }
94}
95
96impl<'de, T> BitUnpackWithArgs<'de> for Box<T>
97where
98 T: BitUnpackWithArgs<'de>,
99{
100 type Args = T::Args;
101
102 #[inline]
103 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
104 where
105 R: BitReader<'de>,
106 {
107 reader.unpack_as_with::<_, FromInto<T>>(args)
108 }
109}
110
111impl<'de, T> BitUnpackWithArgs<'de> for Rc<T>
112where
113 T: BitUnpackWithArgs<'de>,
114{
115 type Args = T::Args;
116
117 #[inline]
118 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
119 where
120 R: BitReader<'de>,
121 {
122 reader.unpack_as_with::<_, FromInto<T>>(args)
123 }
124}
125
126impl<'de, T> BitUnpackWithArgs<'de> for Arc<T>
127where
128 T: BitUnpackWithArgs<'de>,
129{
130 type Args = T::Args;
131
132 #[inline]
133 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
134 where
135 R: BitReader<'de>,
136 {
137 reader.unpack_as_with::<_, FromInto<T>>(args)
138 }
139}
140
141impl<'de, T> BitUnpackWithArgs<'de> for Cow<'_, T>
143where
144 T: ToOwned + ?Sized,
145 T::Owned: BitUnpackWithArgs<'de>,
146{
147 type Args = <T::Owned as BitUnpackWithArgs<'de>>::Args;
148
149 #[inline]
150 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
151 where
152 R: BitReader<'de>,
153 {
154 reader.unpack_with::<T::Owned>(args).map(Self::Owned)
155 }
156}
157
158impl<'de, Left, Right> BitUnpackWithArgs<'de> for Either<Left, Right>
164where
165 Left: BitUnpackWithArgs<'de>,
166 Right: BitUnpackWithArgs<'de, Args = Left::Args>,
167{
168 type Args = Left::Args;
169
170 #[inline]
171 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
172 where
173 R: BitReader<'de>,
174 {
175 match reader.unpack().context("tag")? {
176 false => reader.unpack_with(args).map(Either::Left).context("left"),
177 true => reader.unpack_with(args).map(Either::Right).context("right"),
178 }
179 }
180}
181
182impl<'de, T> BitUnpackWithArgs<'de> for Option<T>
188where
189 T: BitUnpackWithArgs<'de>,
190{
191 type Args = T::Args;
192
193 #[inline]
194 fn unpack_with<R>(mut reader: R, args: Self::Args) -> Result<Self, R::Error>
195 where
196 R: BitReader<'de>,
197 {
198 reader.unpack_as_with::<_, Either<(), Same>>(args)
199 }
200}
201
202impl<'de> BitUnpackWithArgs<'de> for BitVec<u8, Msb0> {
203 type Args = usize;
205
206 #[inline]
207 fn unpack_with<R>(mut reader: R, len: Self::Args) -> Result<Self, R::Error>
208 where
209 R: BitReader<'de>,
210 {
211 reader
212 .unpack_as_with::<Cow<BitSlice<u8, Msb0>>, BorrowCow>(len)
213 .map(Cow::into_owned)
214 }
215}
216
217impl<'de> BitUnpackWithArgs<'de> for Vec<u8> {
218 type Args = usize;
220
221 #[inline]
222 fn unpack_with<R>(mut reader: R, len: Self::Args) -> Result<Self, R::Error>
223 where
224 R: BitReader<'de>,
225 {
226 reader
227 .unpack_as_with::<Cow<[u8]>, BorrowCow>(len)
228 .map(Cow::into_owned)
229 }
230}