common_error_build/
lib.rs1use 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 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