1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! Cryiorust derive macro crate
//!
//! Usage example:
//! ```rust
//! use cryiorust::frame::{Array, Frame};
//!
//! #[derive(Frame)]
//! struct MyFrame {
//!     header: Header,
//!     array: Array,
//! }
//! ```
//!
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn;

/// Main derive macro to be used for structures which contain fields ```Array``` and ```Frame```
#[proc_macro_derive(Frame)]
pub fn frame_derive(input: TokenStream) -> TokenStream {
    let ast = syn::parse(input).unwrap();
    impl_frame(&ast)
}

fn impl_frame(ast: &syn::DeriveInput) -> TokenStream {
    let name = &ast.ident;
    let gen = quote! {
        impl Frame for #name {
            fn array(&self) -> &Array {
                &self.array
            }

            fn header(&self) -> &Header {
                &self.header
            }

            fn header_mut(&mut self) -> &mut Header {
                &mut self.header
            }

            fn array_mut(&mut self) -> &mut Array {
                &mut self.array
            }

            fn set_array(&mut self, array: Array) {
                self.array = array;
            }

            fn consume_array(self: Box<Self>) -> Array {
                self.array
            }

            fn take_array(&mut self) -> Array {
                std::mem::take(&mut self.array)
            }
        }
    };
    gen.into()
}