json_parser_simple 0.1.2

simple json parser lib
Documentation
use std::collections::HashMap;

#[derive(Debug)]
pub enum JsonValue {
    Object(HashMap<String, JsonValue>),
    Array(Vec<JsonValue>),
    String(String),
    Number(f64),
    Bool(bool),
    Null,
}

fn json_get_value(value: &str) -> JsonValue {
    let trimmed = value.trim();

    if trimmed == "null" {
        JsonValue::Null
    } else if trimmed == "true" {
        JsonValue::Bool(true)
    } else if trimmed == "false" {
        JsonValue::Bool(false)
    } else if let Ok(number) = trimmed.parse::<f64>() {
        JsonValue::Number(number)
    } else if trimmed.starts_with('\"') && trimmed.ends_with('\"') {
        JsonValue::String(trimmed[1..trimmed.len() - 1].to_string())
    } else if trimmed.starts_with('{') && trimmed.ends_with('}') {
        parse_object(&trimmed[1..trimmed.len() - 1])
    } else if trimmed.starts_with('[') && trimmed.ends_with(']') {
        parse_array(&trimmed[1..trimmed.len() - 1])
    } else {
        JsonValue::String(trimmed.to_string())
    }
}


fn parse_object(value: &str) -> JsonValue {
    let mut object = HashMap::new();
    let mut key = String::new();
    let mut val = String::new();
    let mut in_key = true;
    let mut in_string = false;
    let mut depth = 0;
    let mut chars = value.chars().peekable();

    while let Some(ch) = chars.next() {
        match ch {
            '{' | '[' => {
                depth += 1;
                if in_key {
                    key.push(ch);
                } else {
                    val.push(ch);
                }
                while let Some(inner_ch) = chars.next() {
                    match inner_ch {
                        '}' | ']' => {
                            depth -= 1;
                            if in_key {
                                key.push(inner_ch);
                            } else {
                                val.push(inner_ch);
                            }
                            if depth == 0 {
                                break;
                            }
                        }
                        _ => {
                            if in_key {
                                key.push(inner_ch);
                            } else {
                                val.push(inner_ch);
                            }
                        }
                    }
                }
            }
            ':' if depth == 0 && in_key => {
                in_key = false;
            }
            ',' if depth == 0 => {
                object.insert(key.trim().trim_matches('\"').to_string(), json_get_value(val.trim()));
                key = String::new();
                val = String::new();
                in_key = true;
            }
            _ => {
                if in_key {
                    key.push(ch);
                } else {
                    val.push(ch);
                }
            }
        }
    }
    if !key.is_empty() {
        object.insert(key.trim().trim_matches('\"').to_string(), json_get_value(val.trim()));
    }
    JsonValue::Object(object)
}

fn parse_array(value: &str) -> JsonValue {
    let mut elements = Vec::new();
    let mut element = String::new();
    let mut depth = 0;
    let mut chars = value.chars().peekable();

    while let Some(ch) = chars.next() {
        match ch {
            '{' | '[' => {
                depth += 1;
                element.push(ch);
                while let Some(inner_ch) = chars.next() {
                    match inner_ch {
                        '}' | ']' => {
                            depth -= 1;
                            element.push(inner_ch);
                            if depth == 0 {
                                break;
                            }
                        }
                        _ => element.push(inner_ch),
                    }
                }
            }
            ',' if depth == 0 => {
                elements.push(json_get_value(element.trim()));
                element = String::new();
            }
            _ => element.push(ch),
        }
    }
    if !element.is_empty() {
        elements.push(json_get_value(element.trim()));
    }
    JsonValue::Array(elements)
}


pub fn json_scan(json: &str) -> HashMap<String, JsonValue> {
    if let JsonValue::Object(object) = json_get_value(json) {
        object
    } else {
        HashMap::new()
    }
}