1use crate::coder::{Buffer, Decoder, Encoder, View};
2use crate::consume::expect_eof;
3use crate::Error;
4use alloc::vec::Vec;
5use core::num::NonZeroUsize;
6
7mod array;
8mod atomic;
9pub(crate) mod convert;
10mod duration;
11mod empty;
12mod impls;
13#[cfg(feature = "std")]
16mod ip_addr;
17mod map;
18mod option;
19mod result;
20mod smart_ptr;
21mod variant;
22pub(crate) mod vec;
23
24#[cfg(feature = "derive")]
26#[doc(hidden)]
27pub mod __private {
28 extern crate alloc;
29 pub use crate::coder::{uninit_field, Buffer, Decoder, Encoder, Result, View};
30 pub use crate::derive::variant::{VariantDecoder, VariantEncoder};
31 pub use crate::derive::{Decode, Encode};
32 pub fn invalid_enum_variant<T>() -> Result<T> {
33 crate::error::err("invalid enum variant")
34 }
35 pub use alloc::vec::Vec;
36}
37
38pub trait Encode {
42 #[doc(hidden)]
43 type Encoder: Encoder<Self>;
44}
45
46pub trait Decode<'a>: Sized {
50 #[doc(hidden)]
51 type Decoder: Decoder<'a, Self>;
52}
53
54pub trait DecodeOwned: for<'de> Decode<'de> {}
58impl<T> DecodeOwned for T where T: for<'de> Decode<'de> {}
59
60#[inline(never)]
63fn encode_inline_never<T: Encode + ?Sized>(encoder: &mut T::Encoder, t: &T) {
64 encoder.encode(t);
65}
66#[inline(never)]
67fn decode_inline_never<'a, T: Decode<'a>>(decoder: &mut T::Decoder) -> T {
68 decoder.decode()
69}
70
71pub fn encode<T: Encode + ?Sized>(t: &T) -> Vec<u8> {
75 let mut encoder = T::Encoder::default();
76 encoder.reserve(NonZeroUsize::new(1).unwrap());
77 encode_inline_never(&mut encoder, t);
78 encoder.collect()
79}
80
81pub fn decode<'a, T: Decode<'a>>(mut bytes: &'a [u8]) -> Result<T, Error> {
85 let mut decoder = T::Decoder::default();
86 decoder.populate(&mut bytes, 1)?;
87 expect_eof(bytes)?;
88 Ok(decode_inline_never(&mut decoder))
89}
90
91impl crate::buffer::Buffer {
92 pub fn encode<'a, T: Encode + ?Sized>(&'a mut self, t: &T) -> &'a [u8] {
94 let encoder = unsafe { self.registry.get_non_static::<T::Encoder>() };
96 encoder.reserve(NonZeroUsize::new(1).unwrap());
97 encode_inline_never(encoder, t);
98 self.out.clear();
99 encoder.collect_into(&mut self.out);
100 self.out.as_slice()
101 }
102
103 pub fn decode<'a, T: Decode<'a>>(&mut self, mut bytes: &'a [u8]) -> Result<T, Error> {
105 let decoder = unsafe { self.registry.get_non_static::<T::Decoder>() };
111 decoder.populate(&mut bytes, 1)?;
112 expect_eof(bytes)?;
113 Ok(decode_inline_never(decoder))
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use crate::{Decode, Encode};
120 use alloc::vec::Vec;
121
122 #[test]
123 fn decode() {
124 macro_rules! test {
125 ($v:expr, $t:ty) => {
126 let v = $v;
127 let encoded = super::encode::<$t>(&v);
128 #[cfg(feature = "std")]
129 println!("{:<24} {encoded:?}", stringify!($t));
130 assert_eq!(v, super::decode::<$t>(&encoded).unwrap());
131 };
132 }
133
134 test!(("abc", "123"), (&str, &str));
135 test!(Vec::<Option<i16>>::new(), Vec<Option<i16>>);
136 test!(vec![None, Some(1), None], Vec<Option<i16>>);
137 test!((0, 1), (usize, isize));
138 test!(vec![true; 255], Vec<bool>);
139 test!([0, 1], [u8; 2]);
140 test!([0, 1, 2], [u8; 3]);
141 test!([0, -1, 0, -1, 0, -1, 0], [i8; 7]);
142 test!([], [u8; 0]);
143 }
144
145 #[derive(Encode, Decode)]
146 enum Never {}
147
148 #[derive(Encode, Decode)]
149 enum One {
150 A(u8),
151 }
152
153 #[derive(Encode, Decode)]
155 enum Two {
156 A(u8),
157 B(i8),
158 }
159
160 #[derive(Encode, Decode)]
161 struct TupleStruct(u8, i8);
162
163 #[derive(Encode, Decode)]
164 struct Generic<T>(T);
165
166 #[derive(Encode, Decode)]
167 struct GenericManual<T>(#[bitcode(bound_type = "T")] T);
168
169 #[derive(Encode, Decode)]
170 struct GenericWhere<A, B>(A, B)
171 where
172 A: From<B>;
173
174 #[derive(Encode, Decode)]
175 struct Lifetime<'a>(&'a str);
176
177 #[derive(Encode, Decode)]
178 struct LifetimeWhere<'a, 'b>(&'a str, &'b str)
179 where
180 'a: 'b;
181
182 #[derive(Encode, Decode)]
183 struct ConstGeneric<const N: usize>([u8; N]);
184
185 #[derive(Encode, Decode)]
186 struct Empty;
187
188 #[derive(Encode, Decode)]
189 struct AssociatedConst([u8; Self::N]);
190 impl AssociatedConst {
191 const N: usize = 1;
192 }
193
194 #[derive(Encode, Decode)]
195 struct AssociatedConstTrait([u8; <Self as Trait>::N]);
196 trait Trait {
197 const N: usize;
198 }
199 impl Trait for AssociatedConstTrait {
200 const N: usize = 1;
201 }
202
203 #[test]
204 fn skipped_fields() {
205 macro_rules! test_skip {
206 ($a:expr, $b:expr, $t:ty) => {
207 let v = $a;
208 let encoded = super::encode::<$t>(&v);
209 #[cfg(feature = "std")]
210 println!("{:<24} {encoded:?}", stringify!($t));
211 assert_eq!($b, super::decode::<$t>(&encoded).unwrap());
212 };
213 }
214
215 #[derive(Encode, Decode, Debug, PartialEq)]
216 struct LifetimeSkipped<'a>(#[bitcode(skip)] &'a str);
217
218 let skipped_string = alloc::string::String::from("I'm skipped!");
219 let lifetime = LifetimeSkipped(&skipped_string);
220 test_skip!(lifetime, LifetimeSkipped(""), LifetimeSkipped);
221
222 #[derive(Encode, Decode, Debug, PartialEq)]
223 struct SkipStruct {
224 pub a: u32,
225 #[bitcode(skip)]
226 pub b: u32,
227 }
228
229 #[derive(Encode, Decode, Debug, PartialEq)]
230 struct SkipTuple(bool, #[bitcode(skip)] u32, u8, #[bitcode(skip)] u8, i32);
231
232 #[derive(Encode, Decode, Debug, PartialEq)]
233 enum SkipEnumTuple {
234 A(u8, u32),
235 B(bool, #[bitcode(skip)] u32, u8, #[bitcode(skip)] u8, i32),
236 }
237
238 #[derive(Default, Debug, PartialEq)]
239 struct Skipped(u32);
240
241 #[derive(Encode, Decode, Debug, PartialEq)]
242 enum SkipEnumStruct {
243 A {
244 a: u8,
245 #[bitcode(skip)]
246 b: Skipped,
247 c: u8,
248 #[bitcode(skip)]
249 d: u8,
250 e: u8,
251 },
252 B,
253 }
254
255 #[derive(Encode, Decode, Debug, PartialEq)]
256 struct SkipGeneric<A, B> {
257 present: A,
258 #[bitcode(skip)]
259 skipped: B,
260 }
261
262 #[derive(Encode, Decode, Debug, PartialEq)]
263 struct PartialSkipGeneric<A, B> {
264 present: A,
265 also_present: B,
266 #[bitcode(skip)]
267 skipped: B,
268 }
269
270 #[derive(Encode, Decode, Debug, PartialEq)]
271 struct SkipAll {
272 #[bitcode(skip)]
273 skipped: u8,
274 }
275
276 #[derive(Encode, Decode, Debug, PartialEq)]
277 struct SkipAllGeneric<A> {
278 #[bitcode(skip)]
279 skipped: A,
280 }
281
282 #[derive(Default, Debug, PartialEq)]
283 struct Indirect<A> {
284 field: A,
285 }
286
287 #[derive(Encode, Decode, Debug, PartialEq)]
288 struct SkipIndirectGeneric<A> {
289 #[bitcode(skip)]
290 skipped: Indirect<A>,
291 }
292
293 test_skip!(
294 SkipStruct { a: 231, b: 9696 },
295 SkipStruct { a: 231, b: 0 },
296 SkipStruct
297 );
298 test_skip!(
299 SkipTuple(true, 23, 231, 42, -13),
300 SkipTuple(true, 0, 231, 0, -13),
301 SkipTuple
302 );
303 test_skip!(
304 SkipEnumTuple::B(true, 23, 231, 42, -42),
305 SkipEnumTuple::B(true, 0, 231, 0, -42),
306 SkipEnumTuple
307 );
308 test_skip!(
309 SkipEnumStruct::A {
310 a: 1,
311 b: Skipped(2),
312 c: 3,
313 d: 4,
314 e: 5
315 },
316 SkipEnumStruct::A {
317 a: 1,
318 b: Skipped(0),
319 c: 3,
320 d: 0,
321 e: 5
322 },
323 SkipEnumStruct
324 );
325 test_skip! {
326 SkipAll {
327 skipped: 42u8,
328 },
329 SkipAll {
330 skipped: 0u8,
331 },
332 SkipAll
333 }
334 assert_eq!(bitcode::encode(&SkipAll { skipped: 42u8 }).len(), 0);
335 test_skip!(
336 SkipGeneric {
337 present: 42u8,
338 skipped: Skipped(231),
339 },
340 SkipGeneric {
341 present: 42u8,
342 skipped: Skipped(0),
343 },
344 SkipGeneric<u8, Skipped>
345 );
346 test_skip!(
347 PartialSkipGeneric {
348 present: 42u8,
349 also_present: 231i32,
350 skipped: 77i32,
351 },
352 PartialSkipGeneric {
353 present: 42u8,
354 also_present: 231i32,
355 skipped: 0i32,
356 },
357 PartialSkipGeneric<u8, i32>
358 );
359 test_skip! {
360 SkipAllGeneric {
361 skipped: 42i32,
362 },
363 SkipAllGeneric {
364 skipped: 0i32,
365 },
366 SkipAllGeneric<i32>
367 }
368 test_skip! {
369 SkipIndirectGeneric {
370 skipped: Indirect{ field: 42i32 },
371 },
372 SkipIndirectGeneric {
373 skipped: Indirect{ field: 0i32 },
374 },
375 SkipIndirectGeneric<i32>
376 }
377 assert_eq!(bitcode::encode(&SkipAllGeneric { skipped: 42u8 }).len(), 0);
378 }
379
380 #[test]
381 fn skipped_fields_regression() {
382 #[derive(Encode, Decode, Default, Debug, PartialEq)]
383 pub struct Indirect<A>(A);
384 #[derive(Encode, Decode, Debug, PartialEq)]
385 struct SkipGeneric<A> {
386 #[bitcode(bound_type = "Indirect<A>")]
387 present: Indirect<A>,
388 }
389 }
390}