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}