pinenut_derive/lib.rs
1//! The internal derive crate for `Pinenut`. Implements the following derive
2//! macros: `pinenut_derive::Builder`, `pinenut_derive::Encode`,
3//! `pinenut_derive::Decode`.
4
5use proc_macro::TokenStream;
6use syn::{parse_macro_input, DeriveInput};
7
8use crate::{
9 builder::impl_builder,
10 codec::{impl_decode, impl_encode},
11};
12
13mod builder;
14mod codec;
15mod misc;
16
17/// `Derive Macro` to automatically implement the `Builder Pattern` for structs that
18/// already implement the `Default` and `Clone` traits.
19///
20/// # Examples
21///
22/// Use it as follows:
23///
24/// ```
25/// use pinenut_derive::Builder;
26///
27/// #[derive(Builder, Default, Clone)]
28/// pub struct MyStruct<T> {
29/// field_one: i32,
30/// field_two: String,
31/// field_three: T,
32/// }
33/// ```
34///
35/// Will generate code looks like this:
36///
37/// ```
38/// # #[derive(Default, Clone)]
39/// # pub struct MyStruct<T> {
40/// # field_one: i32,
41/// # field_two: String,
42/// # field_three: T,
43/// # }
44/// pub struct MyStructBuilder<T: Default + Clone>(MyStruct<T>);
45///
46/// impl<T: Default + Clone> MyStruct<T> {
47/// pub fn builder() -> MyStructBuilder<T> {
48/// MyStructBuilder::new()
49/// }
50/// }
51///
52/// impl<T: Default + Clone> MyStructBuilder<T> {
53/// pub fn new() -> Self {
54/// Self(Default::default())
55/// }
56///
57/// pub fn build(&self) -> MyStruct<T> {
58/// Clone::clone(&self.0)
59/// }
60///
61/// pub fn field_one(&mut self, field_one: i32) -> &mut Self {
62/// self.0.field_one = field_one;
63/// self
64/// }
65///
66/// pub fn field_two(&mut self, field_two: String) -> &mut Self {
67/// self.0.field_two = field_two;
68/// self
69/// }
70///
71/// pub fn field_three(&mut self, field_three: T) -> &mut Self {
72/// self.0.field_three = field_three;
73/// self
74/// }
75/// }
76/// ```
77#[proc_macro_derive(Builder)]
78pub fn derive_builder(input: TokenStream) -> TokenStream {
79 let input = parse_macro_input!(input as DeriveInput);
80 impl_builder(input).into()
81}
82
83/// `Derive Macro` to automatically implement the `Encode` trait for structs.
84///
85/// # Examples
86///
87/// Use it as follows:
88///
89/// ```ignore
90/// use pinenut_derive::Encode;
91///
92/// #[derive(Encode)]
93/// struct MyStruct<'a, T> {
94/// field_one: T,
95/// field_two: &'a str,
96/// }
97/// ```
98///
99/// Will generate code looks like this:
100///
101/// ```ignore
102/// impl<'a, T: codec::Encode> codec::Encode for MyStruct<'a, T> {
103/// fn encode<S>(&self, sink: &mut S) -> Result<(), S::Error>
104/// where
105/// S: codec::Sink,
106/// {
107/// codec::Encode::encode(&self.field_one, sink)?;
108/// codec::Encode::encode(&self.field_two, sink)?;
109/// Ok(())
110/// }
111/// }
112/// ```
113#[proc_macro_derive(Encode)]
114pub fn derive_encode(input: TokenStream) -> TokenStream {
115 let input = parse_macro_input!(input as DeriveInput);
116 impl_encode(input).into()
117}
118
119/// `Derive Macro` to automatically implement the `Decode` trait for structs.
120///
121/// # Examples
122///
123/// Use it as follows:
124///
125/// ```ignore
126/// use pinenut_derive::Encode;
127///
128/// #[derive(Decode)]
129/// struct MyStruct<'a, T> {
130/// field_one: T,
131/// field_two: &'a str,
132/// }
133/// ```
134///
135/// Will generate code looks like this:
136///
137/// ```ignore
138/// impl<'de: 'a, 'a, T: codec::Decode<'de>> codec::Decode<'de> for MyStruct<'a, T> {
139/// fn decode<S>(source: &mut S) -> Result<Self, S::Error>
140/// where
141/// S: codec::Source<'de>,
142/// {
143/// Ok(MyStruct {
144/// field_one: codec::Decode::decode(source)?,
145/// field_two: codec::Decode::decode(source)?,
146/// })
147/// }
148/// }
149/// ```
150#[proc_macro_derive(Decode)]
151pub fn derive_decode(input: TokenStream) -> TokenStream {
152 let input = parse_macro_input!(input as DeriveInput);
153 impl_decode(input).into()
154}