Skip to main content

iepub_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 iepub_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 mut v: Vec<&str> = s.split(',').collect();
22    let doc = v.remove(0);
23    let m = r#"
24    #[doc = {doc}]
25    pub fn set_{method}<T:  AsRef<str>>(&mut self, {method}: T) {
26        if let Some( c) = &mut self.{prefix}{method} {
27            c.clear();
28            c.push_str({method}.as_ref());
29        } else {
30            self.{prefix}{method} = Some(String::from({method}.as_ref()));
31        }
32    }
33    #[doc = {doc}]
34    pub fn with_{method}<T:  AsRef<str>>(mut self, {method}: T) ->Self {
35        self.set_{method}({method}.as_ref());
36        self
37    }
38    #[doc = {doc}]
39    pub fn {method}(&self) -> Option<&str> {
40        self.{prefix}{method}.as_ref().map(|x|x.as_str())
41    }"#
42    .replace("{doc}", doc);
43    if v.len() == 2 {
44        let r = m
45            .replace("{prefix}", format!("{}.", v[0].trim()).as_str().trim())
46            .replace("{method}", v[1].trim());
47        return r.parse().unwrap();
48    } else if v.len() == 1 {
49        return m
50            .replace("{prefix}", "")
51            .replace("{method}", v[0].trim())
52            .parse()
53            .unwrap();
54    }
55    "".parse().unwrap()
56}