common_error_build/
lib.rs

1use std::error::Error;
2use std::fs;
3use std::path::Path;
4
5use quote::__private::TokenStream;
6use quote::quote;
7use regex::Regex;
8use syn::__private::Span;
9use syn::Ident;
10
11use crate::read_csv::{ErrorInfo, read_csv_with_serde};
12
13pub fn error_build() {
14    let dest_path = Path::new("src").join("_common_error.rs");
15
16    if dest_path.exists() {
17        fs::remove_file(dest_path.clone()).unwrap();
18    }
19
20
21    let vec = match read_csv_with_serde("common-error.csv") {
22        Ok(re) => re,
23        Err(e) => {
24            eprintln!("red file error {}", e);
25            return;
26        }
27    };
28
29    let mut file_content = String::from("extern crate common_error; \n \n");
30    let temp_reg = Regex::new(r"(\{[^{}]*\})").unwrap();
31    let arg_reg = Regex::new(r"([a-z_]+-)+[a-z_]+").unwrap();
32
33    file_content.push_str("\n");
34    for x in vec {
35        let string = expanded_error(x, &temp_reg, &arg_reg).to_string();
36        file_content.push_str(string.as_str());
37        file_content.push_str("\n")
38    }
39    fs::write(&dest_path, file_content).unwrap();
40}
41
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn test() {
49        let re = Regex::new(r"(\{[^{}]*\})").unwrap();
50        ;
51        let result = Regex::new(r"([a-z_]+-)+[a-z_]+").unwrap();
52        let template = "{}{}";
53        let args = "a-b";
54        assert!(result.is_match(args));
55        let xxx: Vec<&str> = args.split("-").collect();
56        assert!(re.split(template).into_iter().count() - 1 == xxx.len())
57    }
58}
59
60
61fn expanded_error(recode: ErrorInfo, temp_reg: &Regex, args_reg: &Regex) -> TokenStream {
62    let ErrorInfo { code, template, args, desc } = recode;
63    if !args_reg.is_match(args.as_str()) {
64        eprintln!("error code [{}]  args wrong: {}", code, args);
65    }
66    let args: Vec<&str> = args.split("-").collect();
67    let i = temp_reg.find_iter(template.as_str()).count();
68    if i != args.len() {
69        eprintln!("error code [{}]  args num no match template", code);
70    }
71
72    let templates: Vec<&str> = temp_reg.split(template.as_str()).collect();
73    expand_args_template(code, desc, templates, args)
74}
75
76
77fn expand_args_template(code: String, desc: String, templates: Vec<&str>, args: Vec<&str>) -> TokenStream {
78    let code_str = code.to_string();
79    let code_ident = Ident::new(code.as_str(), Span::call_site());
80
81    if args.len() == 1 {
82        let temp0 = *templates.get(0).unwrap();
83        let temp1 = *templates.get(1).unwrap();
84        let arg0 = Ident::new(*args.get(0).unwrap(), Span::call_site());
85        return quote!(
86             #[doc = #desc]
87            pub struct #code_ident;
88            impl  #code_ident {
89                pub fn throw(#arg0 :&str)->(common_error::CommonError,String){
90                     let msg = #temp0.to_string() + #arg0 + #temp1;
91                     let common_error = common_error::CommonError{code:#code_str.to_string(),message:msg.clone()};
92                     (common_error,msg)
93                }
94            }
95
96        );
97    }
98
99    if args.len() == 2 {
100        let temp0 = *templates.get(0).unwrap();
101        let temp1 = *templates.get(1).unwrap();
102        let temp2 = *templates.get(2).unwrap();
103        let arg0 = Ident::new(*args.get(0).unwrap(), Span::call_site());
104        let arg1 = Ident::new(*args.get(1).unwrap(), Span::call_site());
105        return quote!(
106             #[doc = #desc]
107            pub struct #code_ident;
108            impl  #code_ident {
109                pub fn throw(#arg0 :&str,#arg1 :&str)->(common_error::CommonError,String){
110                     let msg = #temp0.to_string() + #arg0 + #temp1 + #arg1 + #temp2;
111                     let common_error = common_error::CommonError{code:#code_str.to_string(),message:msg.clone()};
112                     (common_error,msg)
113                }
114            }
115
116        );
117    }
118
119
120    if args.len() == 3 {
121        let temp0 = *templates.get(0).unwrap();
122        let temp1 = *templates.get(1).unwrap();
123        let temp2 = *templates.get(2).unwrap();
124        let temp3 = *templates.get(3).unwrap();
125        let arg0 = Ident::new(*args.get(0).unwrap(), Span::call_site());
126        let arg1 = Ident::new(*args.get(1).unwrap(), Span::call_site());
127        let arg2 = Ident::new(*args.get(2).unwrap(), Span::call_site());
128        return quote!(
129             #[doc = #desc]
130            pub struct #code_ident;
131            impl  #code_ident {
132                pub fn throw(#arg0 :&str,#arg1 :&str ,#arg2 :&str)->(common_error::CommonError,String){
133                     let msg = #temp0.to_string() + #arg0 + #temp1 + #arg1 + #temp2 + #arg2 + #temp3;
134                     let common_error = common_error::CommonError{code:#code_str.to_string(),message:msg.clone()};
135                     (common_error,msg)
136                }
137            }
138
139        );
140    }
141
142
143    if args.len() == 4 {
144        let temp0 = *templates.get(0).unwrap();
145        let temp1 = *templates.get(1).unwrap();
146        let temp2 = *templates.get(2).unwrap();
147        let temp3 = *templates.get(3).unwrap();
148        let temp4 = *templates.get(4).unwrap();
149        let arg0 = Ident::new(*args.get(0).unwrap(), Span::call_site());
150        let arg1 = Ident::new(*args.get(1).unwrap(), Span::call_site());
151        let arg2 = Ident::new(*args.get(2).unwrap(), Span::call_site());
152        let arg3 = Ident::new(*args.get(3).unwrap(), Span::call_site());
153        return quote!(
154              #[doc = #desc]
155            pub struct #code_ident;
156            impl  #code_ident {
157                pub fn throw(#arg0 :&str,#arg1 :&str ,#arg2 :&str,#arg3 :&str)->(common_error::CommonError,String){
158                     let msg = #temp0.to_string() + #arg0 + #temp1 + #arg1 + #temp2 + #arg2 + #temp3 + #arg3 + #temp4;
159                     let common_error = common_error::CommonError{code:#code_str.to_string(),message:msg.clone()};
160                     (common_error,msg)
161                }
162            }
163
164        );
165    }
166
167
168    if args.len() == 5 {
169        let temp0 = *templates.get(0).unwrap();
170        let temp1 = *templates.get(1).unwrap();
171        let temp2 = *templates.get(2).unwrap();
172        let temp3 = *templates.get(3).unwrap();
173        let temp4 = *templates.get(4).unwrap();
174        let temp5 = *templates.get(5).unwrap();
175        let arg0 = Ident::new(*args.get(0).unwrap(), Span::call_site());
176        let arg1 = Ident::new(*args.get(1).unwrap(), Span::call_site());
177        let arg2 = Ident::new(*args.get(2).unwrap(), Span::call_site());
178        let arg3 = Ident::new(*args.get(3).unwrap(), Span::call_site());
179        let arg4 = Ident::new(*args.get(4).unwrap(), Span::call_site());
180        return quote!(
181          #[doc = #desc]
182            pub struct #code_ident;
183            impl  #code_ident {
184                pub fn throw(#arg0 :&str,#arg1 :&str ,#arg2 :&str,#arg3 :&str,#arg4 :&str)->(common_error::CommonError,String){
185                     let msg = #temp0.to_string() + #arg0 + #temp1 + #arg1 + #temp2 + #arg2 + #temp3 + #arg3 + #temp4+ #arg4 + #temp5;
186                     let common_error = common_error::CommonError{code:#code_str.to_string(),message:msg.clone()};
187                     (common_error,msg)
188                }
189            }
190
191        );
192    }
193
194    let temp0 = *templates.get(0).unwrap();
195    // == 0 的情况
196    quote!(
197        #[doc = #desc]
198        pub struct #code_ident;
199        impl  #code_ident {
200            pub fn throw()->(common_error::CommonError,String){
201                 let common_error = common_error::CommonError{code:#code_str.to_string(),message:#temp0};
202                 (common_error,#temp0)
203            }
204         }
205
206     )
207}
208
209mod read_csv {
210    use std::error::Error;
211    use std::fs::File;
212
213    use csv::Reader;
214    use serde::Deserialize;
215
216    #[derive(Deserialize, Debug)]
217    pub(crate) struct ErrorInfo {
218        pub code: String,
219        pub desc: String,
220        pub template: String,
221        pub args: String,
222    }
223
224    pub(crate) fn read_csv_with_serde(file_path: &str) -> Result<Vec<ErrorInfo>, Box<dyn Error>> {
225        let file = File::open(file_path)?;
226        let mut rdr = Reader::from_reader(file);
227        let mut vec = Vec::new();
228        for result in rdr.deserialize() {
229            let record: ErrorInfo = result?;
230            vec.push(record);
231        }
232        Ok(vec)
233    }
234}
235