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 => {
57            Ok(Value::Bool(value.as_bool().unwrap_or(false)))
58        }
59        simd_json::ValueType::I64 => {
60            if let Some(i) = value.as_i64() {
61                Ok(serde_json::Number::from(i).into())
62            } else {
63                Ok(Value::Null)
64            }
65        }
66        simd_json::ValueType::I128 => {
67            // For i128, convert to f64 as serde_json doesn't support i128 directly
68            if let Some(i) = value.as_i128() {
69                Ok(serde_json::Number::from_f64(i as f64)
70                    .map(Value::Number)
71                    .unwrap_or(Value::Null))
72            } else {
73                Ok(Value::Null)
74            }
75        }
76        simd_json::ValueType::U64 => {
77            if let Some(u) = value.as_u64() {
78                Ok(serde_json::Number::from(u).into())
79            } else {
80                Ok(Value::Null)
81            }
82        }
83        simd_json::ValueType::U128 => {
84            // For u128, convert to f64 as serde_json doesn't support u128 directly
85            if let Some(u) = value.as_u128() {
86                Ok(serde_json::Number::from_f64(u as f64)
87                    .map(Value::Number)
88                    .unwrap_or(Value::Null))
89            } else {
90                Ok(Value::Null)
91            }
92        }
93        simd_json::ValueType::F64 => {
94            if let Some(f) = value.as_f64() {
95                serde_json::Number::from_f64(f)
96                    .map(Value::Number)
97                    .ok_or_else(|| "Invalid float value".to_string())
98            } else {
99                Ok(Value::Null)
100            }
101        }
102        simd_json::ValueType::String => {
103            if let Some(s) = value.as_str() {
104                Ok(Value::String(s.to_string()))
105            } else {
106                Ok(Value::Null)
107            }
108        }
109        simd_json::ValueType::Array => {
110            if let Some(arr) = value.as_array() {
111                let mut result = Vec::with_capacity(arr.len());
112                for item in arr {
113                    result.push(convert_simd_to_serde(item)?);
114                }
115                Ok(Value::Array(result))
116            } else {
117                Ok(Value::Array(Vec::new()))
118            }
119        }
120        simd_json::ValueType::Object => {
121            if let Some(obj) = value.as_object() {
122                let mut result = serde_json::Map::with_capacity(obj.len());
123                for (key, val) in obj.iter() {
124                    result.insert(key.to_string(), convert_simd_to_serde(val)?);
125                }
126                Ok(Value::Object(result))
127            } else {
128                Ok(Value::Object(serde_json::Map::new()))
129            }
130        }
131        simd_json::ValueType::Extended(_) => {
132            // Extended types - fallback to null
133            Ok(Value::Null)
134        }
135        _ => {
136            // Any other types - fallback to null
137            Ok(Value::Null)
138        }
139    }
140}
141
142/// Read JSON file using SIMD acceleration
143/// Reads file into memory and uses fast SIMD parsing
144pub fn read_json_file(path: &str) -> Result<Value, String> {
145    let bytes = std::fs::read(path)
146        .map_err(|e| format!("Failed to read file {}: {}", path, e))?;
147    parse_json_bytes(bytes)
148}
149