json_validate_rs 0.3.42

validate json schema
Documentation
use json::JsonValue;
use std::collections::HashSet;
use md5::compute as md5Hasher;

pub fn hash_md5(v:&Vec<u8>)->String{
    format!("{:?}",md5Hasher(v))
}

pub fn init(v1:&JsonValue,v2:&JsonValue)->bool{

    let c_type = get_json_type(v1);
    let n_type = get_json_type(v2);
    if c_type != n_type{return false;}
    let data_type = c_type;

    if data_type == "object"{
        if v1.len() != v2.len(){
            return false;
        }
        for (key,value) in v1.entries(){
            if !v2.has_key(key){return false;}
            if !init(value, &v2[key]){return false;}
        }
    } else if data_type == "array"{
        if v1.len() != v2.len(){
            return false;
        }
        let mut v1_hashes = HashSet::new();
        for item in v1.members(){
            v1_hashes.insert(get_safe_hash(item));
        }
        for item in v2.members(){
            let v2_hash = get_safe_hash(item);
            if !v1_hashes.contains(&v2_hash){
                return false;
            }
        }
    } else if data_type == "string"{
        if v1 != v2{return false;}
    } else if data_type == "number"{
        if v1 != v2{return false;}
    } else if data_type == "bool"{
        if v1 == true && v2 == true{
            return true;
        } else if v1 == false && v2 == false{
            return true;
        } else {
            return false;
        }
    } else if data_type == "null"{
        if v1 != v2{return false;}
    } else {
        if v1 != v2{return false;}
    }

    return true;

}

pub fn get_safe_hash(v:&JsonValue)->String{

    let data_type = get_json_type(v);

    if data_type == "object"{
        let mut keys = vec![];
        for (key,_) in v.entries(){
            keys.push(key);
        }
        keys.sort();
        let mut build = String::new();
        for key in keys{
            let value_hash = get_safe_hash(&v[key]);
            build.push_str(&format!("{}:{}",key,value_hash));
        }
        return hash_md5(&build.as_bytes().to_vec());
    }

    if data_type == "string"{
        let val = v.as_str().unwrap();
        return hash_md5(&val.as_bytes().to_vec());
    }

    if data_type == "number"{
        let val = v.as_f64().unwrap();
        return hash_md5(&val.to_be_bytes().to_vec());
    }

    if data_type == "bool"{
        let val = v.as_bool().unwrap();
        if val == true{
            return hash_md5(&"true".as_bytes().to_vec());
        } else {
            return hash_md5(&"false".as_bytes().to_vec());
        }
    }

    if data_type == "array"{
        let mut hashes = vec![];
        for item in v.members(){
            hashes.push(get_safe_hash(item));
        }
        hashes.sort();
        let mut build = String::new();
        for item in hashes{
            build.push_str(&format!("_{}",item));
        }
        return hash_md5(&build.as_bytes().to_vec());
    }

    if data_type == "null"{
        return hash_md5(&"null".as_bytes().to_vec());
    }

    return hash_md5(&"none".as_bytes().to_vec());

}

fn get_json_type(data:&JsonValue)->&'static str{
    let hold;
    if data.is_object(){hold = "object";} else
    if data.is_array(){hold = "array";} else
    if data.is_string(){hold = "string";} else
    if data.is_number(){hold = "number";} else
    if data.is_boolean(){hold = "bool";} else
    if data.is_null(){hold = "null";} else
    {hold = "none";}
    return hold;
}