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}