add_macro_impl_fromstr/
lib.rs

1extern crate proc_macro;
2use proc_macro::TokenStream;
3use syn::{ parse_macro_input, DeriveInput };
4use quote::quote;
5
6/// This macros provides the implementation of the trait [FromStr](std::str::FromStr) (writed for crate [add_macro](https://docs.rs/add_macro))
7/// 
8/// # Examples:
9/// ```
10/// use add_macro_impl_fromstr::FromStr;
11/// 
12/// #[derive(Debug)]
13/// enum Error {
14///     ParseError,
15/// }
16/// 
17/// #[derive(FromStr)]
18/// struct Email {
19///     name: String,
20///     host: String
21/// }
22/// 
23/// impl Email {
24///     // WARNING: this method needs for working the implementation trait FromStr
25///     pub fn parse(s: &str) -> Result<Self, Error> {
26///         let spl = s.trim().splitn(2, "@").collect::<Vec<_>>();
27///         
28///         if spl.len() == 2 {
29///             Ok(Self {
30///                 name: spl[0].to_owned(),
31///                 host: spl[1].to_owned(),
32///             })
33///         } else {
34///             Err(Error::ParseError)
35///         }
36///     }
37/// }
38/// 
39/// fn main() -> Result<(), Error> {
40///     let _bob_email: Email = "bob@example.loc".parse()?;
41/// 
42///     Ok(())
43/// }
44/// ```
45#[proc_macro_derive(FromStr)]
46pub fn derive_fromstr(input: TokenStream) -> TokenStream {
47    let parsed = parse_macro_input!(input as DeriveInput);
48    let name = &parsed.ident;
49    
50    quote!{
51        impl ::core::str::FromStr for #name {
52            type Err = Error;
53            
54            fn from_str(s: &str) -> ::core::result::Result<Self, Self::Err> {
55                Self::parse(s)
56            }
57        }
58    }
59    .into()
60}