json_eval_rs/
json_parser.rs

1/// Hybrid SIMD-accelerated JSON parser with fallback to serde_json
2/// Uses simd-json for maximum performance on large JSON data
3use serde_json::Value;
4
5/// Parse JSON from a string slice using SIMD acceleration when possible
6/// Falls back to serde_json for compatibility
7#[inline]
8pub fn parse_json_str(json: &str) -> Result<Value, String> {
9    // Try SIMD-JSON first for performance
10    parse_simd_str(json).or_else(|_| {
11        // Fallback to serde_json if SIMD fails
12        serde_json::from_str(json).map_err(|e| e.to_string())
13    })
14}
15
16/// Parse JSON from bytes using SIMD acceleration when possible
17/// This is the fastest path as simd-json works on mutable byte slices
18#[inline]
19pub fn parse_json_bytes(mut bytes: Vec<u8>) -> Result<Value, String> {
20    // SIMD-JSON requires mutable bytes for in-place parsing
21    parse_simd_bytes(&mut bytes).or_else(|_| {
22        // Fallback to serde_json
23        serde_json::from_slice(&bytes).map_err(|e| e.to_string())
24    })
25}
26
27/// Internal SIMD parser for string slices
28#[inline]
29fn parse_simd_str(json: &str) -> Result<Value, String> {
30    let mut bytes = json.as_bytes().to_vec();
31    parse_simd_bytes(&mut bytes)
32}
33
34/// Internal SIMD parser for mutable byte slices (fastest path)
35#[inline]
36fn parse_simd_bytes(bytes: &mut [u8]) -> Result<Value, String> {
37    // Use simd-json for SIMD-accelerated parsing
38    match simd_json::to_borrowed_value(bytes) {
39        Ok(borrowed_value) => {
40            // Convert simd_json::BorrowedValue to serde_json::Value
41            // This is efficient as simd-json value types are compatible
42            convert_simd_to_serde(&borrowed_value)
43        }
44        Err(e) => Err(e.to_string()),
45    }
46}
47
48/// Convert simd_json::BorrowedValue to serde_json::Value
49/// Optimized for zero-copy where possible
50#[inline]
51fn convert_simd_to_serde(value: &simd_json::BorrowedValue) -> Result<Value, String> {
52    use simd_json::prelude::*;
53
54    match value.value_type() {
55        simd_json::ValueType::Null => Ok(Value::Null),
56        simd_json::ValueType::Bool => Ok(Value::Bool(value.as_bool().unwrap_or(false))),
57        simd_json::ValueType::I64 => {
58            if let Some(i) = value.as_i64() {
59                Ok(serde_json::Number::from(i).into())
60            } else {
61                Ok(Value::Null)
62            }
63        }
64        simd_json::ValueType::I128 => {
65            // For i128, convert to f64 as serde_json doesn't support i128 directly
66            if let Some(i) = value.as_i128() {
67                Ok(serde_json::Number::from_f64(i as f64)
68                    .map(Value::Number)
69                    .unwrap_or(Value::Null))
70            } else {
71                Ok(Value::Null)
72            }
73        }
74        simd_json::ValueType::U64 => {
75            if let Some(u) = value.as_u64() {
76                Ok(serde_json::Number::from(u).into())
77            } else {
78                Ok(Value::Null)
79            }
80        }
81        simd_json::ValueType::U128 => {
82            // For u128, convert to f64 as serde_json doesn't support u128 directly
83            if let Some(u) = value.as_u128() {
84                Ok(serde_json::Number::from_f64(u as f64)
85                    .map(Value::Number)
86                    .unwrap_or(Value::Null))
87            } else {
88                Ok(Value::Null)
89            }
90        }
91        simd_json::ValueType::F64 => {
92            if let Some(f) = value.as_f64() {
93                serde_json::Number::from_f64(f)
94                    .map(Value::Number)
95                    .ok_or_else(|| "Invalid float value".to_string())
96            } else {
97                Ok(Value::Null)
98            }
99        }
100        simd_json::ValueType::String => {
101            if let Some(s) = value.as_str() {
102                Ok(Value::String(s.to_string()))
103            } else {
104                Ok(Value::Null)
105            }
106        }
107        simd_json::ValueType::Array => {
108            if let Some(arr) = value.as_array() {
109                let mut result = Vec::with_capacity(arr.len());
110                for item in arr {
111                    result.push(convert_simd_to_serde(item)?);
112                }
113                Ok(Value::Array(result))
114            } else {
115                Ok(Value::Array(Vec::new()))
116            }
117        }
118        simd_json::ValueType::Object => {
119            if let Some(obj) = value.as_object() {
120                let mut result = serde_json::Map::with_capacity(obj.len());
121                for (key, val) in obj.iter() {
122                    result.insert(key.to_string(), convert_simd_to_serde(val)?);
123                }
124                Ok(Value::Object(result))
125            } else {
126                Ok(Value::Object(serde_json::Map::new()))
127            }
128        }
129        simd_json::ValueType::Extended(_) => {
130            // Extended types - fallback to null
131            Ok(Value::Null)
132        }
133        _ => {
134            // Any other types - fallback to null
135            Ok(Value::Null)
136        }
137    }
138}
139
140/// Read JSON file using SIMD acceleration
141/// Reads file into memory and uses fast SIMD parsing
142pub fn read_json_file(path: &str) -> Result<Value, String> {
143    let bytes = std::fs::read(path).map_err(|e| format!("Failed to read file {}: {}", path, e))?;
144    parse_json_bytes(bytes)
145}