add_macro_impl_from/
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_from_enum;
9mod impl_struct;            use impl_struct::impl_from_struct;
10
11/// This macros provides the implementation of trait [From<T>](std::convert::From) (writed for crate [add_macro](https://docs.rs/add_macro))
12/// 
13/// # Examples:
14/// ```
15/// use add_macro_impl_from::From;
16/// 
17/// #[derive(Debug)]
18/// enum SimpleError {
19///     Wrong,
20/// }
21///
22/// impl std::fmt::Display for SimpleError {
23///     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
24///         match &self {
25///             Self::Wrong => write!(f, "Something went wrong.. =/"),
26///         }
27///     }
28/// }
29///
30/// #[derive(Debug)]
31/// struct SuperError {
32///     source: String,
33/// }
34///
35/// impl std::fmt::Display for SuperError {
36///     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37///         write!(f, "{}", &self.source)
38///     }
39/// }
40///
41/// #[derive(Debug, From)]
42/// #[from("std::io::Error" = "Self::Io(v)")]       // result: impl From<std::io::Error> for Error { fn from(v: std::io::Error) -> Self { Self::Io(v) } }
43/// enum Error {
44///     Io(std::io::Error),
45///
46///     #[from]
47///     Simple(SimpleError),
48///
49///     #[from = "SuperError { source: format!(\"Super error: {}\", v.source) }"]
50///     Super(SuperError),
51///
52///     #[from("String")]
53///     #[from("&str" = "v.to_owned()")]
54///     #[from("i32" = "format!(\"Error code: {v}\")")]
55///     Stringify(String),
56/// }
57///
58/// impl std::fmt::Display for Error {
59///     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
60///         match &self {
61///             Self::Io(e) => write!(f, "{e}"),
62///             Self::Simple(e) => write!(f, "{e}"),
63///             Self::Super(e) => write!(f, "{e}"),
64///             Self::Stringify(e) => write!(f, "{e}"),
65///         }
66///     }
67/// }
68///
69/// fn main() {
70///     let _io_err = Error::from( std::fs::read("fake/path/to/file").unwrap_err() );
71///
72///     let simple_err = Error::from( SimpleError::Wrong );
73///     assert_eq!(format!("{simple_err}"), "Something went wrong.. =/");
74///
75///     let super_err = Error::from( SuperError { source: "Bad request".to_owned() } );
76///     assert_eq!(format!("{super_err}"), "Super error: Bad request");
77///
78///     let str_err = Error::from( String::from("Something went wrong.. =/") );
79///     assert_eq!(format!("{str_err}"), "Something went wrong.. =/");
80///
81///     let str_err2 = Error::from("Something went wrong.. =/");
82///     assert_eq!(format!("{str_err2}"), "Something went wrong.. =/");
83///
84///     let str_err3 = Error::from(404);
85///     assert_eq!(format!("{str_err3}"), "Error code: 404");
86/// }
87/// ```
88#[proc_macro_derive(From, attributes(from))]
89pub fn derive_from(input: TokenStream) -> TokenStream {
90    let item = parse_item(input.into()).unwrap();
91    
92    match item {
93        Item::Enum(data) => match impl_from_enum(data) {
94            Ok(output) => output.into(),
95            Err(e) => panic!("{e}")
96        },
97
98        Item::Struct(data) => match impl_from_struct(data) {
99            Ok(output) => output.into(),
100            Err(e) => panic!("{e}")
101        },
102
103        _ => panic!("{}", Error::ImplementationError)
104    }
105}