bitcode/derive/
mod.rs
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;
8pub(crate) mod convert;
9mod duration;
10mod empty;
11mod impls;
12#[cfg(feature = "std")]
15mod ip_addr;
16mod map;
17mod option;
18mod result;
19mod smart_ptr;
20mod variant;
21pub(crate) mod vec;
22
23#[cfg(feature = "derive")]
25#[doc(hidden)]
26pub mod __private {
27 extern crate alloc;
28 pub use crate::coder::{uninit_field, Buffer, Decoder, Encoder, Result, View};
29 pub use crate::derive::variant::{VariantDecoder, VariantEncoder};
30 pub use crate::derive::{Decode, Encode};
31 pub fn invalid_enum_variant<T>() -> Result<T> {
32 crate::error::err("invalid enum variant")
33 }
34 pub use alloc::vec::Vec;
35}
36
37pub trait Encode {
41 #[doc(hidden)]
42 type Encoder: Encoder<Self>;
43}
44
45pub trait Decode<'a>: Sized {
49 #[doc(hidden)]
50 type Decoder: Decoder<'a, Self>;
51}
52
53pub trait DecodeOwned: for<'de> Decode<'de> {}
57impl<T> DecodeOwned for T where T: for<'de> Decode<'de> {}
58
59#[inline(never)]
62fn encode_inline_never<T: Encode + ?Sized>(encoder: &mut T::Encoder, t: &T) {
63 encoder.encode(t);
64}
65#[inline(never)]
66fn decode_inline_never<'a, T: Decode<'a>>(decoder: &mut T::Decoder) -> T {
67 decoder.decode()
68}
69
70pub fn encode<T: Encode + ?Sized>(t: &T) -> Vec<u8> {
74 let mut encoder = T::Encoder::default();
75 encoder.reserve(NonZeroUsize::new(1).unwrap());
76 encode_inline_never(&mut encoder, t);
77 encoder.collect()
78}
79
80pub fn decode<'a, T: Decode<'a>>(mut bytes: &'a [u8]) -> Result<T, Error> {
84 let mut decoder = T::Decoder::default();
85 decoder.populate(&mut bytes, 1)?;
86 expect_eof(bytes)?;
87 Ok(decode_inline_never(&mut decoder))
88}
89
90impl crate::buffer::Buffer {
91 pub fn encode<'a, T: Encode + ?Sized>(&'a mut self, t: &T) -> &'a [u8] {
93 let encoder = unsafe { self.registry.get_non_static::<T::Encoder>() };
95 encoder.reserve(NonZeroUsize::new(1).unwrap());
96 encode_inline_never(encoder, t);
97 self.out.clear();
98 encoder.collect_into(&mut self.out);
99 self.out.as_slice()
100 }
101
102 pub fn decode<'a, T: Decode<'a>>(&mut self, mut bytes: &'a [u8]) -> Result<T, Error> {
104 let decoder = unsafe { self.registry.get_non_static::<T::Decoder>() };
110 decoder.populate(&mut bytes, 1)?;
111 expect_eof(bytes)?;
112 Ok(decode_inline_never(decoder))
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use crate::{Decode, Encode};
119 use alloc::vec::Vec;
120
121 #[test]
122 fn decode() {
123 macro_rules! test {
124 ($v:expr, $t:ty) => {
125 let v = $v;
126 let encoded = super::encode::<$t>(&v);
127 #[cfg(feature = "std")]
128 println!("{:<24} {encoded:?}", stringify!($t));
129 assert_eq!(v, super::decode::<$t>(&encoded).unwrap());
130 };
131 }
132
133 test!(("abc", "123"), (&str, &str));
134 test!(Vec::<Option<i16>>::new(), Vec<Option<i16>>);
135 test!(vec![None, Some(1), None], Vec<Option<i16>>);
136 test!((0, 1), (usize, isize));
137 test!(vec![true; 255], Vec<bool>);
138 test!([0, 1], [u8; 2]);
139 test!([0, 1, 2], [u8; 3]);
140 test!([0, -1, 0, -1, 0, -1, 0], [i8; 7]);
141 test!([], [u8; 0]);
142 }
143
144 #[derive(Encode, Decode)]
145 enum Never {}
146
147 #[derive(Encode, Decode)]
148 enum One {
149 A(u8),
150 }
151
152 #[derive(Encode, Decode)]
154 enum Two {
155 A(u8),
156 B(i8),
157 }
158
159 #[derive(Encode, Decode)]
160 struct TupleStruct(u8, i8);
161
162 #[derive(Encode, Decode)]
163 struct Generic<T>(T);
164
165 #[derive(Encode, Decode)]
166 struct GenericManual<T>(#[bitcode(bound_type = "T")] T);
167
168 #[derive(Encode, Decode)]
169 struct GenericWhere<A, B>(A, B)
170 where
171 A: From<B>;
172
173 #[derive(Encode, Decode)]
174 struct Lifetime<'a>(&'a str);
175
176 #[derive(Encode, Decode)]
177 struct LifetimeWhere<'a, 'b>(&'a str, &'b str)
178 where
179 'a: 'b;
180
181 #[derive(Encode, Decode)]
182 struct ConstGeneric<const N: usize>([u8; N]);
183
184 #[derive(Encode, Decode)]
185 struct Empty;
186
187 #[derive(Encode, Decode)]
188 struct AssociatedConst([u8; Self::N]);
189 impl AssociatedConst {
190 const N: usize = 1;
191 }
192
193 #[derive(Encode, Decode)]
194 struct AssociatedConstTrait([u8; <Self as Trait>::N]);
195 trait Trait {
196 const N: usize;
197 }
198 impl Trait for AssociatedConstTrait {
199 const N: usize = 1;
200 }
201}