diff --git a/src/lib.rs b/src/lib.rs index cdcb0e1..85feac9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,26 +1,56 @@ -use serde_json::Value; +use serde_json::{Map, Value}; use std::ffi::{CStr, CString}; use std::os::raw::c_char; -#[no_mangle] -pub extern "C" fn parse_json(input: *const c_char) -> *mut c_char { - let c_str = unsafe { - assert!(!input.is_null()); - - CStr::from_ptr(input) - }; +fn parse_value(value: &Value) -> String { + match value { + Value::Null => "null".to_string(), + Value::Bool(val) => val.to_string(), + Value::Number(val) => val.to_string(), + Value::String(val) => format!("\"{}\"", val), + Value::Array(val) => { + let mut result = String::new(); + result.push('['); + for item in val { + result += &parse_value(item); + result.push(','); + } + if !val.is_empty() { + result.pop(); + } + result.push(']'); + result + } + Value::Object(val) => { + let mut result = String::new(); + result.push('{'); + for (key, value) in val { + result.push_str(&format!("\"{}\":", key)); + result += &parse_value(value); + result.push(','); + } + if !val.is_empty() { + result.pop(); + } + result.push('}'); + result + } + } +} - let input_str = match c_str.to_str() { +#[no_mangle] +pub unsafe extern "C" fn parse_json(input: *const c_char) -> *mut c_char { + let input_str = match CStr::from_ptr(input).to_str() { Ok(str) => str, Err(_) => return CString::new("").unwrap().into_raw(), }; - let result = serde_json::from_str::(input_str); + let result = match serde_json::from_str::(input_str) { + Ok(data) => parse_value(&data), + Err(err) => format!("Failed to parse JSON: {}", err), + }; - match result { - Ok(data) => CString::new(format!("{:?}", data)).unwrap().into_raw(), - Err(err) => CString::new(format!("Failed to parse JSON: {}", err)) - .unwrap() - .into_raw(), - } + CString::new(result) + .map(|s| s.into_raw()) + .unwrap_or_else(|_| CString::new("").unwrap().into_raw()) }