add_macro_impl_display/
lib.rs

1extern crate proc_macro;
2use proc_macro::TokenStream;
3use venial::{ parse_item, Item };
4
5pub(crate) mod error;
6pub(crate) mod tools;
7pub(crate) mod prelude;     use prelude::*;
8mod impl_enum;              use impl_enum::impl_display_enum;
9mod impl_struct;            use impl_struct::impl_display_struct;
10
11/// This macros provides the implementation of trait [Display](std::fmt::Display) (writed for crate [add_macro](https://docs.rs/add_macro))
12/// 
13/// # Examples:
14/// ```
15/// use add_macro_impl_display::Display;
16/// 
17/// #[derive(Display)]
18/// enum Animals {
19///     Turtle,
20///   
21///     #[display]
22///     Bird,
23///    
24///     #[display = "The Cat"]
25///     Cat,
26/// 
27///     #[display("The Dog")]
28///     Dog,
29///
30///     Other(&'static str),
31///
32///     #[display]
33///     Other2(&'static str),
34/// 
35///     #[display("{0} {1}, {2} years old")]
36///     Info(Box<Self>, &'static str, i32),
37///
38///     #[display("{kind} {name}, {age} years old")] 
39///     Info2 {
40///         kind: Box<Self>,
41///         name: &'static str,
42///         age: i32,
43///     },
44/// }
45///
46/// fn main() {
47///     assert_eq!(format!("{}", Animals::Turtle), "Turtle");
48///     assert_eq!(format!("{}", Animals::Bird), "Bird");
49///     assert_eq!(format!("{}", Animals::Cat), "The Cat");
50///     assert_eq!(format!("{}", Animals::Dog), "The Dog");
51///     assert_eq!(format!("{}", Animals::Other("Tiger")), "Tiger");
52///     assert_eq!(format!("{}", Animals::Other2("Tiger")), "Tiger");
53///     assert_eq!(format!("{}", Animals::Info(Box::new(Animals::Cat), "Tomas", 2)), "The Cat Tomas, 2 years old");
54///     assert_eq!(format!("{}", 
55///         Animals::Info2 {
56///             kind: Box::new(Animals::Cat),
57///             name: "Tomas",
58///             age: 2,
59///         }),
60///         "The Cat Tomas, 2 years old"
61///     );
62/// }
63/// ```
64/// ```
65/// use add_macro_impl_display::Display;
66/// 
67/// #[derive(Debug, Display)]
68/// struct Person {
69///     pub name: String,
70///     pub age: u8,
71///     pub email: String,
72/// }
73/// 
74/// #[derive(Debug, Display)]
75/// #[display("Hello, {name}! Your age is {age} years old.{email:.0}")]  // NOTE: if you don't need to use one of field, that use {field_name:.0} syntax
76/// struct PersonInfo {
77///     pub name: String,
78///     pub age: u8,
79///     pub email: String,
80/// }
81///
82/// fn main() {
83///     assert_eq!(
84///         format!("{}", Person {
85///             name: "Bob".to_owned(),
86///             age: 22,
87///             email: "bob@example.loc".to_owned()
88///         }),
89///         r#"Person { name: "Bob", age: 22, email: "bob@example.loc" }"#
90///     );
91/// 
92///     assert_eq!(
93///         format!("{}", PersonInfo {
94///             name: "Bob".to_owned(),
95///             age: 22,
96///             email: "bob@example.loc".to_owned()
97///         }),
98///         "Hello, Bob! Your age is 22 years old."
99///     );
100/// }
101/// ```
102#[proc_macro_derive(Display, attributes(display))]
103pub fn derive_display(input: TokenStream) -> TokenStream {
104    let item = parse_item(input.into()).unwrap();
105    
106    match item {
107        Item::Enum(data) => impl_display_enum(data).unwrap().into(),
108        Item::Struct(data) => impl_display_struct(data).unwrap().into(),
109        _ => panic!("{}", Error::ImplementationError)
110    }
111}