extern crate proc_macro; use proc_macro::TokenStream; use venial::{ parse_item, Item }; pub(crate) mod error; pub(crate) mod tools; pub(crate) mod prelude; use prelude::*; mod impl_enum; use impl_enum::impl_from_enum; mod impl_struct; use impl_struct::impl_from_struct; /// This macros provides the implementation of trait [From](std::convert::From) (writed for crate [add_macro](https://docs.rs/add_macro)) /// /// # Examples: /// ``` /// use add_macro_impl_from::From; /// /// #[derive(Debug)] /// enum SimpleError { /// Wrong, /// } /// /// impl std::fmt::Display for SimpleError { /// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { /// match &self { /// Self::Wrong => write!(f, "Something went wrong.. =/"), /// } /// } /// } /// /// #[derive(Debug)] /// struct SuperError { /// source: String, /// } /// /// impl std::fmt::Display for SuperError { /// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { /// write!(f, "{}", &self.source) /// } /// } /// /// #[derive(Debug, From)] /// #[from("std::io::Error" = "Self::Io(v)")] // result: impl From for Error { fn from(v: std::io::Error) -> Self { Self::Io(v) } } /// enum Error { /// Io(std::io::Error), /// /// #[from] /// Simple(SimpleError), /// /// #[from = "SuperError { source: format!(\"Super error: {}\", v.source) }"] /// Super(SuperError), /// /// #[from("String")] /// #[from("&str" = "v.to_owned()")] /// #[from("i32" = "format!(\"Error code: {v}\")")] /// Stringify(String), /// } /// /// impl std::fmt::Display for Error { /// fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { /// match &self { /// Self::Io(e) => write!(f, "{e}"), /// Self::Simple(e) => write!(f, "{e}"), /// Self::Super(e) => write!(f, "{e}"), /// Self::Stringify(e) => write!(f, "{e}"), /// } /// } /// } /// /// fn main() { /// let _io_err = Error::from( std::fs::read("fake/path/to/file").unwrap_err() ); /// /// let simple_err = Error::from( SimpleError::Wrong ); /// assert_eq!(format!("{simple_err}"), "Something went wrong.. =/"); /// /// let super_err = Error::from( SuperError { source: "Bad request".to_owned() } ); /// assert_eq!(format!("{super_err}"), "Super error: Bad request"); /// /// let str_err = Error::from( String::from("Something went wrong.. =/") ); /// assert_eq!(format!("{str_err}"), "Something went wrong.. =/"); /// /// let str_err2 = Error::from("Something went wrong.. =/"); /// assert_eq!(format!("{str_err2}"), "Something went wrong.. =/"); /// /// let str_err3 = Error::from(404); /// assert_eq!(format!("{str_err3}"), "Error code: 404"); /// } /// ``` #[proc_macro_derive(From, attributes(from))] pub fn derive_from(input: TokenStream) -> TokenStream { let item = parse_item(input.into()).unwrap(); match item { Item::Enum(data) => match impl_from_enum(data) { Ok(output) => output.into(), Err(e) => panic!("{e}") }, Item::Struct(data) => match impl_from_struct(data) { Ok(output) => output.into(), Err(e) => panic!("{e}") }, _ => panic!("{}", Error::ImplementationError) } }