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;
8mod atomic;
9pub(crate) mod convert;
10mod duration;
11mod empty;
12mod impls;
13// TODO: When ip_in_core has been stable (https://github.com/rust-lang/rust/issues/108443)
14// for long enough, remove feature check.
15#[cfg(feature = "std")]
16mod ip_addr;
17mod map;
18mod option;
19mod result;
20mod smart_ptr;
21mod variant;
22pub(crate) mod vec;
23
24// For derive macro.
25#[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
38/// A type which can be encoded to bytes with [`encode`].
39///
40/// Use `#[derive(Encode)]` to implement.
41pub trait Encode {
42    #[doc(hidden)]
43    type Encoder: Encoder<Self>;
44}
45
46/// A type which can be decoded from bytes with [`decode`].
47///
48/// Use `#[derive(Decode)]` to implement.
49pub trait Decode<'a>: Sized {
50    #[doc(hidden)]
51    type Decoder: Decoder<'a, Self>;
52}
53
54/// A type which can be decoded without borrowing any bytes from the input.
55///
56/// This type is a shorter version of `for<'de> Decode<'de>`.
57pub trait DecodeOwned: for<'de> Decode<'de> {}
58impl<T> DecodeOwned for T where T: for<'de> Decode<'de> {}
59
60// Stop #[inline(always)] of Encoder::encode/Decoder::decode since 90% of the time is spent in these
61// functions, and we don't want extra code interfering with optimizations.
62#[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
71/// Encodes a `T:` [`Encode`] into a [`Vec<u8>`].
72///
73/// **Warning:** The format is subject to change between major versions.
74pub 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
81/// Decodes a [`&[u8]`][`prim@slice`] into an instance of `T:` [`Decode`].
82///
83/// **Warning:** The format is subject to change between major versions.
84pub 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    /// Like [`encode`], but saves allocations between calls.
93    pub fn encode<'a, T: Encode + ?Sized>(&'a mut self, t: &T) -> &'a [u8] {
94        // Safety: Encoders don't have any lifetimes (they don't contain T either).
95        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    /// Like [`decode`], but saves allocations between calls.
104    pub fn decode<'a, T: Decode<'a>>(&mut self, mut bytes: &'a [u8]) -> Result<T, Error> {
105        // Safety: Decoders have dangling pointers to `bytes` from previous calls which haven't been
106        // cleared. This isn't an issue in practice because they remain as pointers in FastSlice and
107        // aren't dereferenced. If we wanted to be safer we could clear all the decoders but this
108        // would result in lots of extra code to maintain and a performance/binary size hit.
109        // To detect misuse we run miri tests/cargo fuzz where bytes goes out of scope between calls.
110        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    // cargo expand --lib --tests | grep -A15 Two
154    #[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}