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}