Skip to main content

zepub_derive/
lib.rs

1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4
5///
6///
7/// 对于Option<String>类型的结构体成员,生成相关方法,支持多级嵌套
8///
9///
10/// ```compile_fail
11/// use zepub_derive::option_string_method;
12/// // 访问成员 self.info.k
13/// option_string_method!(info,k);
14/// // 访问成员 self.k
15/// option_string_method!(k);
16/// ```
17///
18#[proc_macro]
19pub fn option_string_method(input: TokenStream) -> TokenStream {
20    let s = input.to_string();
21    let v: Vec<&str> = s.split(',').collect();
22
23    let m = r#"pub fn set_{method}<T:  AsRef<str>>(&mut self, {method}: T) {
24        if let Some( c) = &mut self.{prefix}{method} {
25            c.clear();
26            c.push_str({method}.as_ref());
27        } else {
28            self.{prefix}{method} = Some(String::from({method}.as_ref()));
29        }
30    }
31    pub fn with_{method}<T:  AsRef<str>>(mut self, {method}: T) ->Self {
32        self.set_{method}({method}.as_ref());
33        self
34    }
35    pub fn {method}(&self) -> Option<&str> {
36        self.{prefix}{method}.as_ref().map(|x|x.as_str())
37    }"#;
38    if v.len() == 2 {
39        let r = m
40            .replace("{prefix}", format!("{}.", v[0].trim()).as_str().trim())
41            .replace("{method}", v[1].trim());
42        return r.parse().unwrap();
43    } else if v.len() == 1 {
44        return m
45            .replace("{prefix}", "")
46            .replace("{method}", v[0].trim())
47            .parse()
48            .unwrap();
49    }
50    "".parse().unwrap()
51}