easy_sqlx_utils/
option_parser.rs

1static OPTIONS_TYPE: [&str; 3] = ["Option", "std::option::Option", "core::option::Option"];
2
3pub fn is_option(ty: &str) -> bool {
4    OPTIONS_TYPE.contains(&ty)
5}
6
7pub fn is_vec(ty: &str) -> bool {
8    ty == "Vec"
9}
10
11// pub fn parse_size(lit: &Option<Lit>) -> Option<isize> {
12//      if let Some(len) = lit {
13//         match len {
14//             Lit::Int(l) => {
15//                 let res = l.base10_parse::<isize>();
16//                 if let Ok(sz) = res {
17//                     Some(sz)
18//                 } else {
19//                     None
20//                 }
21//             },
22//             _ => {
23//                 None
24//             }
25//         }
26//     } else { None }
27// }
28
29// pub fn parse_type_as_string(ty: &syn::Type, add_surffix: bool) -> String {
30//     if let syn::Type::Path(p) = ty {
31//         // let paths = p.path.segments.iter().map(|v| v.ident.to_string()).collect::<Vec<String>>();
32//         // return paths.join("::");
33//         let idents_of_path =
34//             p.path
35//                 .segments
36//                 .iter()
37//                 .into_iter()
38//                 .fold(String::new(), |mut acc, v| {
39//                     acc.push_str(&v.ident.to_string());
40//                     if add_surffix {
41//                         acc.push('|');
42//                     }
43//                     acc
44//                 });
45//         return idents_of_path;
46//     }
47//     "".to_string()
48// }
49
50pub fn parse_type_options(ty: &syn::Type) -> (isize, String, &syn::Type, bool) {
51    if let syn::Type::Path(p) = ty {
52        let idents_path = p
53            .path
54            .segments
55            .iter()
56            .map(|v| v.ident.to_string())
57            .collect::<Vec<String>>()
58            .join("::");
59        if is_option(&idents_path.as_str()) {
60            // 是 Option
61            if let Some(p) = p.path.segments.first() {
62                if let syn::PathArguments::AngleBracketed(ref params) = p.arguments {
63                    if let syn::GenericArgument::Type(ref ty) = params.args.first().unwrap() {
64                        // 解析泛型
65                        // 继续下一层解析
66                        let (option_count, path, typ, is_vec) = parse_type_options(ty);
67                        return (option_count + 1, path, typ, is_vec);
68                    }
69                }
70            }
71        }
72
73        if is_vec(&idents_path.as_str()) {
74            // 是 Vec
75            if let Some(p) = p.path.segments.first() {
76                if let syn::PathArguments::AngleBracketed(ref params) = p.arguments {
77                    if let syn::GenericArgument::Type(ref ty_gen) = params.args.first().unwrap() {
78                        // 解析泛型
79                        // 继续下一层解析
80                        let (option_count, path, _, _) = parse_type_options(ty_gen);
81                        if path == "u8" {
82                            // Vec<u8>
83                            return (option_count, "Vec<u8>".to_string(), ty, true);
84                        }
85                    }
86                }
87            }
88        }
89
90        // 不是 Option
91        return (0, idents_path, ty, false);
92    }
93
94    panic!("无法解析类型")
95}
96
97// pub fn parse_types(paths: &mut Vec<&syn::Type>) {
98//     if let syn::Type::Path(p) = paths.last().unwrap() {
99//         let idents_of_path =
100//             p.path
101//                 .segments
102//                 .iter()
103//                 .into_iter()
104//                 .fold(String::new(), |mut acc, v| {
105//                     acc.push_str(&v.ident.to_string());
106//                     acc.push('|');
107//                     acc
108//                 });
109
110//         if is_option(&idents_of_path.as_str()) {
111//             // count += 1;
112//             if let Some(p) = p.path.segments.first() {
113//                 if let syn::PathArguments::AngleBracketed(ref params) = p.arguments {
114//                     if let syn::GenericArgument::Type(ref ty) = params.args.first().unwrap() {
115//                         paths.push(ty);
116//                         parse_types(paths);
117//                         // count = find_option(count, ty);
118//                     }
119//                 }
120//             }
121//         }
122//     }
123//     // count
124// }