encdec_macros/lib.rs
1//! Macros for deriving [`Decode`] and [`Encode`]
2//!
3
4extern crate proc_macro;
5use proc_macro::TokenStream;
6
7mod attrs;
8mod decode;
9mod encode;
10
11/// `#[derive(Encode)]` support.
12///
13/// generates an [`Encode`][encdec_base::encode::Encode] implementation equivalent to calling `.encode()` on each field in order.
14///
15/// for example:
16/// ```
17/// # use encdec_base::{encode::Encode, Error};
18/// #[derive(Debug, PartialEq)]
19/// struct Something {
20/// a: u8,
21/// b: u16,
22/// c: [u8; 3],
23/// }
24///
25/// // `#[derive(Decode)]` equivalent implementation
26/// impl Encode for Something {
27/// type Error = Error;
28///
29/// fn encode_len(&self) -> Result<usize, Self::Error> {
30/// Ok(1 + 2 + 3)
31/// }
32///
33/// fn encode(&self, buff: &mut [u8]) -> Result<usize, Self::Error> {
34/// let mut index = 0;
35/// buff[index] = self.a;
36/// index += 1;
37///
38/// buff[1] = self.b as u8;
39/// buff[2] = (self.b >> 8) as u8;
40/// index += 2;
41///
42/// buff[3..][..3].copy_from_slice(&self.c);
43/// index += 3;
44///
45/// Ok(index)
46/// }
47/// }
48/// ```
49#[proc_macro_derive(Encode, attributes(encdec))]
50pub fn derive_encode_impl(input: TokenStream) -> TokenStream {
51 encode::derive_encode_impl(input)
52}
53
54/// `#[derive(Decode)]` support.
55///
56/// generates a [`Decode`][encdec_base::decode::Decode] implementation equivalent to calling `.decode()` on each field in order.
57///
58/// for example:
59/// ```
60/// # use encdec_base::{decode::Decode, Error};
61/// #[derive(Debug, PartialEq)]
62/// struct Something {
63/// a: u8,
64/// b: u16,
65/// c: [u8; 3],
66/// }
67///
68/// // `#[derive(Decode)]` equivalent implementation
69/// impl <'a> Decode<'a> for Something {
70/// type Output = Something;
71/// type Error = Error;
72///
73/// fn decode(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
74/// let mut index = 0;
75///
76/// let a = buff[0];
77/// index += 1;
78///
79/// let b = buff[1] as u16 | (buff[2] as u16) << 8;
80/// index += 2;
81///
82/// let mut c = [0u8; 3];
83/// c.copy_from_slice(&buff[3..][..3]);
84/// index += 3;
85///
86/// Ok((Self{a, b, c}, index))
87/// }
88/// }
89/// ```
90#[proc_macro_derive(Decode, attributes(encdec))]
91pub fn derive_decode_borrowed_impl(input: TokenStream) -> TokenStream {
92 decode::derive_decode_impl(input, false)
93}
94
95/// `#[derive(DecodeOwned)]` support.
96///
97/// generates a [`DecodeOwned`][encdec_base::decode::DecodeOwned] implementation equivalent to calling `.decode()` on each field in order.
98///
99/// for example:
100/// ```
101/// # use encdec_base::{decode::DecodeOwned, Error};
102/// #[derive(Debug, PartialEq)]
103/// struct Something {
104/// a: u8,
105/// b: u16,
106/// c: [u8; 3],
107/// }
108///
109/// // `#[derive(Decode)]` equivalent implementation
110/// impl DecodeOwned for Something {
111/// type Output = Something;
112/// type Error = Error;
113///
114/// fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
115/// let mut index = 0;
116///
117/// let a = buff[0];
118/// index += 1;
119///
120/// let b = buff[1] as u16 | (buff[2] as u16) << 8;
121/// index += 2;
122///
123/// let mut c = [0u8; 3];
124/// c.copy_from_slice(&buff[3..][..3]);
125/// index += 3;
126///
127/// Ok((Self{a, b, c}, index))
128/// }
129/// }
130/// ```
131#[proc_macro_derive(DecodeOwned, attributes(encdec))]
132pub fn derive_decode_owned_impl(input: TokenStream) -> TokenStream {
133 decode::derive_decode_impl(input, true)
134}