trimmer_derive/
lib.rs

1//! Derive implementation for trimmer template engine
2//!
3//! [Trimmer](https://crates.io/crates/trimmer/) |
4//! [Docs](https://docs.rs/trimmer_derive/) |
5//! [Github](https://github.com/tailhook/trimmer-derive) |
6//! [Crate](https://crates.io/crates/trimmer_derive)
7//!
8//!
9//! This crate allows to derive `trimmer::Variable` trait.
10//!
11//! Currently it supports two kinds of structures, a tuple structure with
12//! a single field (i.e. a newtype pattern):
13//!
14//! ```rust
15//! extern crate trimmer;
16//! #[macro_use] extern crate trimmer_derive;
17//!
18//! #[derive(Debug, Variable)]
19//! struct Variable(String);
20//!
21//! # fn main() {}
22//! ```
23//!
24//! In this case, all methods of the variable implementation will be forwarded
25//! to the enclosed type (and it must implement `Variable`)
26//!
27//! And for regular structures with named patterns:
28//!
29//! ```rust
30//! extern crate trimmer;
31//! #[macro_use] extern crate trimmer_derive;
32//!
33//! #[derive(Debug, Variable)]
34//! struct Point {
35//!     x: u32,
36//!     y: u32,
37//! }
38//!
39//! # fn main() {}
40//! ```
41//!
42//! In this case, `Point` will implement `attr` method resolving `x` and `y`.
43//! All fields must implement `Variable` trait themselves.
44//!
45//!
46#![crate_type="proc-macro"]
47#![recursion_limit="256"]
48#![warn(missing_debug_implementations)]
49
50extern crate syn;
51extern crate proc_macro;
52#[macro_use] extern crate quote;
53
54mod new_types;
55mod structs;
56
57use proc_macro::TokenStream;
58
59
60/// A derivation function for proc macro
61#[proc_macro_derive(Variable, attributes(variable))]
62pub fn derive_variable(input: TokenStream) -> TokenStream {
63    let input: String = input.to_string();
64    let ref ast = syn::parse_macro_input(&input).expect("Couldn't parse item");
65    let str_data = match ast.body {
66        syn::Body::Enum(..) => panic!("Only structs are supported"),
67        syn::Body::Struct(ref str_data) => str_data,
68    };
69    let result = match *str_data {
70        syn::VariantData::Struct(ref fields) => {
71            structs::derive(ast, fields)
72        },
73        syn::VariantData::Unit => {
74            panic!("Can't derive variable for unit struct");
75        },
76        syn::VariantData::Tuple(ref fields) => {
77            if fields.len() == 1 {
78                new_types::derive(ast, &fields[0])
79            } else {
80                unimplemented!();
81            }
82        },
83    };
84    result.to_string().parse().expect("Couldn't parse string to tokens")
85}