-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.rs
More file actions
106 lines (77 loc) · 3.34 KB
/
Copy pathbuild.rs
File metadata and controls
106 lines (77 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Env
use std::env::var as env_var;
use dotenvy::dotenv;
// File get/set stuff
use std::fs::{
read_to_string as read_file,
create_dir_all as mkdir_p,
write as write_file,
};
use reqwest::blocking::get as reqwest_get;
// Parsing JSON Schema
use serde_json::from_str;
// Type stuff
use syn::{ parse2, File };
use prettyplease::unparse;
use schemars::schema::RootSchema;
use typify::{ TypeSpace, TypeSpaceSettings };
fn get_file(url_env: &str, path_env: &str) -> Result<String, String> {
match (env_var(url_env), env_var(path_env)) {
(Ok(_), Ok(_)) => Err(format!("Both {url_env} and {path_env} are set. Please only set one of them")),
(Err(_), Err(_)) => Err(format!("Neither {url_env} nor {path_env} are set. Please set one of them.")),
// URL is set, load file via get request
(Ok(url), Err(_)) => {
let result = reqwest_get(url).map_err(|e| format!("Failed to get request schema file: {}", e))?;
let text = result.text().map_err(|e| format!("Failed to get text from schema file request: {}", e))?;
Ok(text)
},
// Path is set, load file via fs
(Err(_), Ok(path)) => {
let text = read_file(path).map_err(|e| format!("Failed to read schema file: {}", e))?;
Ok(text)
},
}
}
fn text_to_schema(text: &str) -> Result<typify::TypeSpace, String> {
let schema = from_str::<RootSchema>(text).map_err(|e| format!("Failed to parse schema file: {}", e))?;
let mut type_space = TypeSpace::new(TypeSpaceSettings::default().with_struct_builder(false));
type_space.add_root_schema(schema).map_err(|e| format!("Failed to add schema to type space: {}", e))?;
Ok(type_space)
}
const FILE_HEADER: &str = r"
//! This file is autogenerated by the build script.
//! Please do not modify it.
use serde::{Deserialize, Serialize};
";
fn schema_to_file_output(schema: TypeSpace) -> Result<String, String> {
let parsed = parse2::<File>(schema.to_stream())
.map_err(|e| format!("Failed to parse generated code: {e}"))?;
let pretty_printed = unparse(&parsed);
Ok(format!("{}{pretty_printed}", FILE_HEADER.trim_start()))
}
const API_TYPES_FOLDER: &str = "./src/server/utils/api_types";
mod env_vars {
pub const INC_URL: &str = "API_INCOMING_SCHEMA_URL";
pub const INC_PATH: &str = "API_INCOMING_SCHEMA_FILE_PATH";
pub const OUT_URL: &str = "API_OUTGOING_SCHEMA_URL";
pub const OUT_PATH: &str = "API_OUTGOING_SCHEMA_FILE_PATH";
}
fn main() {
dotenv().expect("Failed to load .env file");
use env_vars::*;
let incoming_text = get_file(INC_URL, INC_PATH).unwrap();
let outgoing_text = get_file(OUT_URL, OUT_PATH).unwrap();
let incoming_typespace = text_to_schema(&incoming_text).unwrap();
let outgoing_typespace = text_to_schema(&outgoing_text).unwrap();
let incoming_file_contents = schema_to_file_output(incoming_typespace).unwrap();
let outgoing_file_contents = schema_to_file_output(outgoing_typespace).unwrap();
mkdir_p(API_TYPES_FOLDER).expect("Failed to create api_types directory");
write_file(
format!("{API_TYPES_FOLDER}/incoming.rs"),
incoming_file_contents,
).expect("Failed to write incoming typedefs");
write_file(
format!("{API_TYPES_FOLDER}/outgoing.rs"),
outgoing_file_contents,
).expect("Failed to write outgoing typedefs");
}