actix_cloud/
response_build.rs1use anyhow::Result;
2use quote::{format_ident, quote};
3use std::{
4 env,
5 fs::{read_to_string, File},
6 io::Write,
7 path::Path,
8};
9use walkdir::WalkDir;
10use yaml_rust2::YamlLoader;
11
12#[derive(thiserror::Error, Debug)]
13pub enum BuildError {
14 #[error("response file format invalid")]
15 Format,
16
17 #[error("response file name invalid")]
18 File,
19}
20
21pub fn generate_response(import_prefix: &str, input: &str, output: &str) -> Result<()> {
35 let outfile = Path::new(&env::var("OUT_DIR")?).join(output);
36 let mut output = File::create(&outfile)?;
37 writeln!(
38 output,
39 "use {}actix_cloud::response::ResponseCodeTrait;",
40 import_prefix
41 )?;
42 for entry in WalkDir::new(input) {
43 let entry = entry?;
44 if entry.file_type().is_file() {
45 let file = read_to_string(entry.path())?;
46 let yaml = YamlLoader::load_from_str(&file)?;
47 let doc = &yaml[0];
48 let mut name_vec = Vec::new();
49 let mut code_vec = Vec::new();
50 let mut message_vec = Vec::new();
51 for (name, field) in doc.as_hash().ok_or(BuildError::Format)? {
52 name_vec.push(format_ident!(
53 "{}",
54 name.as_str().ok_or(BuildError::Format)?
55 ));
56 code_vec.push(field["code"].as_i64().ok_or(BuildError::Format)?);
57 message_vec.push(field["message"].as_str().ok_or(BuildError::Format)?);
58 }
59
60 let file_stem = entry.path().file_stem().ok_or(BuildError::File)?;
61 let mut s = file_stem.to_str().ok_or(BuildError::File)?.to_owned();
62 let s = s.remove(0).to_uppercase().to_string() + &s;
63 let enum_name = format_ident!("{}Response", s);
64 let mut enum_code = Vec::new();
65 for i in 0..code_vec.len() {
66 let s = &name_vec[i];
67 let c = code_vec[i];
68 enum_code.push(quote! {#enum_name::#s => #c});
69 }
70 let mut enum_message = Vec::new();
71 for i in 0..code_vec.len() {
72 let s = &name_vec[i];
73 let c = message_vec[i];
74 enum_message.push(quote! {#enum_name::#s => #c});
75 }
76 let content = quote! {
77 pub enum #enum_name {
78 #(#name_vec),*
79 }
80
81 impl ResponseCodeTrait for #enum_name {
82 fn code(&self) -> i64 {
83 match self {
84 #(#enum_code),*
85 }
86 }
87
88 fn message(&self) -> &'static str {
89 match self {
90 #(#enum_message),*
91 }
92 }
93 }
94 };
95
96 write!(
97 output,
98 "{}",
99 prettyplease::unparse(&syn::parse_file(&content.to_string())?)
100 )?;
101 }
102 }
103 Ok(())
104}