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