tlbits/as/
from_into.rs

1use core::{fmt::Display, marker::PhantomData};
2
3use crate::{
4    de::{
5        args::{r#as::BitUnpackAsWithArgs, BitUnpackWithArgs},
6        r#as::BitUnpackAs,
7        BitReader, BitUnpack,
8    },
9    ser::{
10        args::{r#as::BitPackAsWithArgs, BitPackWithArgs},
11        r#as::BitPackAs,
12        BitPack, BitWriter,
13    },
14    Error,
15};
16
17/// Serialize value by converting it to/from a proxy type
18/// with serialization support.
19///
20/// See [`TryFromInto`] for more generalized version of this adapter
21/// which uses [`TryFrom`] trait instead
22pub struct FromInto<T>(PhantomData<T>);
23
24impl<T, As> BitPackAs<T> for FromInto<As>
25where
26    T: Into<As> + Clone,
27    As: BitPack,
28{
29    #[inline]
30    fn pack_as<W>(source: &T, writer: W) -> Result<(), W::Error>
31    where
32        W: BitWriter,
33    {
34        source.clone().into().pack(writer)
35    }
36}
37
38impl<T, As> BitPackAsWithArgs<T> for FromInto<As>
39where
40    T: Into<As> + Clone,
41    As: BitPackWithArgs,
42{
43    type Args = As::Args;
44
45    #[inline]
46    fn pack_as_with<W>(source: &T, writer: W, args: Self::Args) -> Result<(), W::Error>
47    where
48        W: BitWriter,
49    {
50        source.clone().into().pack_with(writer, args)
51    }
52}
53
54impl<T, As> BitUnpackAs<T> for FromInto<As>
55where
56    As: Into<T> + BitUnpack,
57{
58    #[inline]
59    fn unpack_as<R>(reader: R) -> Result<T, R::Error>
60    where
61        R: BitReader,
62    {
63        As::unpack(reader).map(Into::into)
64    }
65}
66
67impl<T, As> BitUnpackAsWithArgs<T> for FromInto<As>
68where
69    As: Into<T> + BitUnpackWithArgs,
70{
71    type Args = As::Args;
72
73    #[inline]
74    fn unpack_as_with<R>(reader: R, args: Self::Args) -> Result<T, R::Error>
75    where
76        R: BitReader,
77    {
78        As::unpack_with(reader, args).map(Into::into)
79    }
80}
81
82/// Serialize a reference value by converting it to/from a proxy type
83/// with serialization support.
84///
85/// See [`TryFromIntoRef`] for more generalized version of this adapter
86/// which uses [`TryFrom`] trait instead
87pub struct FromIntoRef<T>(PhantomData<T>);
88
89impl<T, As> BitPackAs<T> for FromIntoRef<As>
90where
91    for<'a> &'a T: Into<As>,
92    As: BitPack,
93{
94    #[inline]
95    fn pack_as<W>(source: &T, writer: W) -> Result<(), W::Error>
96    where
97        W: BitWriter,
98    {
99        source.into().pack(writer)
100    }
101}
102
103impl<T, As> BitPackAsWithArgs<T> for FromIntoRef<As>
104where
105    for<'a> &'a T: Into<As>,
106    As: BitPackWithArgs,
107{
108    type Args = As::Args;
109
110    #[inline]
111    fn pack_as_with<W>(source: &T, writer: W, args: Self::Args) -> Result<(), W::Error>
112    where
113        W: BitWriter,
114    {
115        source.into().pack_with(writer, args)
116    }
117}
118
119impl<T, As> BitUnpackAs<T> for FromIntoRef<As>
120where
121    As: Into<T> + BitUnpack,
122{
123    #[inline]
124    fn unpack_as<R>(reader: R) -> Result<T, R::Error>
125    where
126        R: BitReader,
127    {
128        As::unpack(reader).map(Into::into)
129    }
130}
131
132impl<T, As> BitUnpackAsWithArgs<T> for FromIntoRef<As>
133where
134    As: Into<T> + BitUnpackWithArgs,
135{
136    type Args = As::Args;
137
138    #[inline]
139    fn unpack_as_with<R>(reader: R, args: Self::Args) -> Result<T, R::Error>
140    where
141        R: BitReader,
142    {
143        As::unpack_with(reader, args).map(Into::into)
144    }
145}
146
147/// Serialize value by converting it to/from a proxy type
148/// with serialization support.
149///
150/// **Note:** [`FromInto`] is more specialized version of this adapter
151/// which the infailable [`Into`] trait instead.
152pub struct TryFromInto<T>(PhantomData<T>);
153
154impl<T, As> BitPackAs<T> for TryFromInto<As>
155where
156    T: TryInto<As> + Clone,
157    <T as TryInto<As>>::Error: Display,
158    As: BitPack,
159{
160    #[inline]
161    fn pack_as<W>(source: &T, writer: W) -> Result<(), W::Error>
162    where
163        W: BitWriter,
164    {
165        source
166            .clone()
167            .try_into()
168            .map_err(Error::custom)?
169            .pack(writer)
170    }
171}
172
173impl<T, As> BitPackAsWithArgs<T> for TryFromInto<As>
174where
175    T: TryInto<As> + Clone,
176    <T as TryInto<As>>::Error: Display,
177    As: BitPackWithArgs,
178{
179    type Args = As::Args;
180
181    #[inline]
182    fn pack_as_with<W>(source: &T, writer: W, args: Self::Args) -> Result<(), W::Error>
183    where
184        W: BitWriter,
185    {
186        source
187            .clone()
188            .try_into()
189            .map_err(Error::custom)?
190            .pack_with(writer, args)
191    }
192}
193
194impl<T, As> BitUnpackAs<T> for TryFromInto<As>
195where
196    As: TryInto<T> + BitUnpack,
197    <As as TryInto<T>>::Error: Display,
198{
199    #[inline]
200    fn unpack_as<R>(reader: R) -> Result<T, R::Error>
201    where
202        R: BitReader,
203    {
204        As::unpack(reader)?.try_into().map_err(Error::custom)
205    }
206}
207
208impl<T, As> BitUnpackAsWithArgs<T> for TryFromInto<As>
209where
210    As: TryInto<T> + BitUnpackWithArgs,
211    <As as TryInto<T>>::Error: Display,
212{
213    type Args = As::Args;
214
215    #[inline]
216    fn unpack_as_with<R>(reader: R, args: Self::Args) -> Result<T, R::Error>
217    where
218        R: BitReader,
219    {
220        As::unpack_with(reader, args)?
221            .try_into()
222            .map_err(Error::custom)
223    }
224}
225
226/// Serialize a reference value by converting it to/from a proxy type
227/// with serialization support.
228///
229/// **Note:** [`FromIntoRef`] is more specialized version of this adapter
230/// which the infailable [`Into`] trait instead.
231pub struct TryFromIntoRef<T>(PhantomData<T>);
232
233impl<T, As> BitPackAs<T> for TryFromIntoRef<As>
234where
235    for<'a> &'a T: TryInto<As>,
236    for<'a> <&'a T as TryInto<As>>::Error: Display,
237    As: BitPack,
238{
239    #[inline]
240    fn pack_as<W>(source: &T, writer: W) -> Result<(), W::Error>
241    where
242        W: BitWriter,
243    {
244        source.try_into().map_err(Error::custom)?.pack(writer)
245    }
246}
247
248impl<T, As> BitPackAsWithArgs<T> for TryFromIntoRef<As>
249where
250    for<'a> &'a T: TryInto<As>,
251    for<'a> <&'a T as TryInto<As>>::Error: Display,
252    As: BitPackWithArgs,
253{
254    type Args = As::Args;
255
256    #[inline]
257    fn pack_as_with<W>(source: &T, writer: W, args: Self::Args) -> Result<(), W::Error>
258    where
259        W: BitWriter,
260    {
261        source
262            .try_into()
263            .map_err(Error::custom)?
264            .pack_with(writer, args)
265    }
266}
267
268impl<T, As> BitUnpackAs<T> for TryFromIntoRef<As>
269where
270    As: TryInto<T> + BitUnpack,
271    <As as TryInto<T>>::Error: Display,
272{
273    #[inline]
274    fn unpack_as<R>(reader: R) -> Result<T, R::Error>
275    where
276        R: BitReader,
277    {
278        As::unpack(reader)?.try_into().map_err(Error::custom)
279    }
280}
281
282impl<T, As> BitUnpackAsWithArgs<T> for TryFromIntoRef<As>
283where
284    As: TryInto<T> + BitUnpackWithArgs,
285    <As as TryInto<T>>::Error: Display,
286{
287    type Args = As::Args;
288
289    #[inline]
290    fn unpack_as_with<R>(reader: R, args: Self::Args) -> Result<T, R::Error>
291    where
292        R: BitReader,
293    {
294        As::unpack_with(reader, args)?
295            .try_into()
296            .map_err(Error::custom)
297    }
298}