zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
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),
                })
            }
        }
    }

    // create the handlebars registry
    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()
}