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}