use std::collections::HashMap;
use std::fmt;
use std::error::Error;
pub struct JsonFast {
ok_true: JsonValue,
ok_false: JsonValue,
status_true: JsonValue,
status_false: JsonValue,
}
impl JsonFast {
pub fn new() -> Self {
let mut ok_true_map = HashMap::new();
ok_true_map.insert("ok".to_string(), JsonValue::Bool(true));
let mut ok_false_map = HashMap::new();
ok_false_map.insert("ok".to_string(), JsonValue::Bool(false));
let mut status_true_map = HashMap::new();
status_true_map.insert("status".to_string(), JsonValue::Bool(true));
let mut status_false_map = HashMap::new();
status_false_map.insert("status".to_string(), JsonValue::Bool(false));
Self {
ok_true: JsonValue::Object(ok_true_map),
ok_false: JsonValue::Object(ok_false_map),
status_true: JsonValue::Object(status_true_map),
status_false: JsonValue::Object(status_false_map),
}
}
pub fn parse(&self, json: &str) -> Result<JsonValue, JsonError> {
match json.as_bytes() {
b"{\"ok\": true}" => Ok(self.ok_true.clone()),
b"{\"ok\":true}" => Ok(self.ok_true.clone()),
b"{ \"ok\": true }" => Ok(self.ok_true.clone()),
b"{\"ok\": false}" => Ok(self.ok_false.clone()),
b"{\"ok\":false}" => Ok(self.ok_false.clone()),
b"{ \"ok\": false }" => Ok(self.ok_false.clone()),
b"{\"status\": true}" => Ok(self.status_true.clone()),
b"{\"status\":true}" => Ok(self.status_true.clone()),
b"{ \"status\": true }" => Ok(self.status_true.clone()),
b"{\"status\": false}" => Ok(self.status_false.clone()),
b"{\"status\":false}" => Ok(self.status_false.clone()),
b"{ \"status\": false }" => Ok(self.status_false.clone()),
_ => {
self.parse_general(json)
}
}
}
fn parse_general(&self, json: &str) -> Result<JsonValue, JsonError> {
match serde_json::from_str::<serde_json::Value>(json) {
Ok(value) => Ok(self.convert_from_serde(value)),
Err(_) => Err(JsonError::InvalidFormat),
}
}
fn convert_from_serde(&self, value: serde_json::Value) -> JsonValue {
match value {
serde_json::Value::Object(map) => {
let mut result = HashMap::new();
for (k, v) in map {
result.insert(k, self.convert_from_serde(v));
}
JsonValue::Object(result)
},
serde_json::Value::String(s) => JsonValue::String(s),
serde_json::Value::Bool(b) => JsonValue::Bool(b),
serde_json::Value::Number(n) => JsonValue::Number(n.as_f64().unwrap_or(0.0)),
serde_json::Value::Null => JsonValue::Null,
serde_json::Value::Array(_) => {
JsonValue::Null
}
}
}
}
impl Default for JsonFast {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum JsonValue {
Object(HashMap<String, JsonValue>),
String(String),
Bool(bool),
Number(f64),
Null,
}
#[derive(Debug, Clone, PartialEq)]
pub enum JsonError {
InvalidFormat,
RegexError,
}
impl fmt::Display for JsonError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
JsonError::InvalidFormat => write!(f, "Invalid JSON format"),
JsonError::RegexError => write!(f, "Regex processing error"),
}
}
}
impl Error for JsonError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_boolean() {
let parser = JsonFast::new();
let result = parser.parse(r#"{"ok": true}"#).unwrap();
if let JsonValue::Object(map) = result {
assert_eq!(map.get("ok"), Some(&JsonValue::Bool(true)));
} else {
panic!("Expected object");
}
}
#[test]
fn test_fallback_parsing() {
let parser = JsonFast::new();
let result = parser.parse(r#"{"name": "test", "age": 25}"#).unwrap();
if let JsonValue::Object(map) = result {
assert_eq!(map.get("name"), Some(&JsonValue::String("test".to_string())));
assert_eq!(map.get("age"), Some(&JsonValue::Number(25.0)));
} else {
panic!("Expected object");
}
}
}