use handlebars::Handlebars;
use crate::prelude2::*;
use super::_TEMPLATE;
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub struct Field {
pub name: String,
pub rust_type: String,
}
pub async fn json_to_struct(body: web::Bytes, request: HttpRequest) -> impl Responder {
let json_string = match crate::commons::bytes_to_string(body.to_vec()) {
Ok(val) => val,
Err(e) => return request.json(200, R::failed(500, e.to_string())),
};
let obj = match serde_json::from_str::<serde_json::Value>(&json_string) {
Ok(obj) => {
if obj.is_array() {
if let Some(arr) = obj.as_array() {
arr.iter().next().map(|item| item.to_owned())
} else {
None
}
} else if obj.is_object() {
Some(obj)
} else {
None
}
}
Err(e) => {
return request.json(200, R::failed(500, e.to_string()));
}
};
let mut fields = Vec::<Field>::new();
if let Some(obj) = obj {
if let Some(obj) = obj.as_object() {
for (k, _v) in obj.iter() {
fields.push(Field {
name: k.to_owned(),
rust_type: get_type(_v),
})
}
}
}
let mut handlebars = Handlebars::new();
#[rustfmt::skip]
handlebars.register_template_string("t1", *_TEMPLATE).unwrap();
let data = serde_json::json!({
"fields": fields,
});
let r = handlebars.render("t1", &data).unwrap();
request.text(200, &r)
}
fn get_type(val: &serde_json::Value) -> String {
if val.is_f64() {
return "Option<f64>".into();
}
if val.is_i64() {
return "Option<i64>".into();
}
if val.is_u64() {
return "Option<u64>".into();
}
if val.is_null() {
return "Option<String>".into();
}
if val.is_number() {
return "Option<usize>".into();
}
if val.is_boolean() {
return "Option<bool>".into();
}
"Option<String>".into()
}