1pub mod allocator;
7pub mod buffer_pool;
8pub mod scanner;
9pub mod simd;
10pub mod simd_zero_copy;
11pub mod simple;
12pub mod sonic;
13pub mod value;
14pub mod zero_copy;
15
16pub use allocator::{AllocatorBackend, AllocatorStats, SimdAllocator, global_allocator};
17pub use buffer_pool::{
18 BufferPool, BufferSize, PoolConfig, PooledBuffer, SimdType, global_buffer_pool,
19};
20pub use scanner::{JsonScanner, ScanResult, StringLocation};
21pub use simd_zero_copy::{
22 SimdParseResult, SimdParsingStats, SimdZeroCopyConfig, SimdZeroCopyParser,
23};
24pub use simple::{ParseConfig, ParseStats, SimpleParser};
25pub use sonic::{LazyFrame, SonicConfig, SonicParser};
26pub use value::{JsonValue, LazyArray, LazyObject};
27pub use zero_copy::{IncrementalParser, LazyJsonValue, LazyParser, MemoryUsage, ZeroCopyParser};
28
29use crate::{Result, SemanticMeta};
30
31pub struct Parser {
33 sonic: SonicParser,
34 simple: SimpleParser,
35 #[allow(dead_code)] zero_copy_simd: Option<SimdZeroCopyParser<'static>>,
37 use_sonic: bool,
38 #[allow(dead_code)] use_zero_copy: bool,
40}
41
42impl Parser {
43 pub fn new() -> Self {
45 Self {
46 sonic: SonicParser::new(),
47 simple: SimpleParser::new(),
48 zero_copy_simd: None, use_sonic: true,
50 use_zero_copy: true, }
52 }
53
54 pub fn with_config(config: ParseConfig) -> Self {
56 let sonic_config = SonicConfig {
57 detect_semantics: config.detect_semantics,
58 max_input_size: config.max_size_mb * 1024 * 1024,
59 };
60
61 Self {
62 sonic: SonicParser::with_config(sonic_config),
63 simple: SimpleParser::with_config(config),
64 zero_copy_simd: None, use_sonic: true,
66 use_zero_copy: true,
67 }
68 }
69
70 pub fn with_serde_fallback() -> Self {
72 Self {
73 sonic: SonicParser::new(),
74 simple: SimpleParser::new(),
75 zero_copy_simd: None,
76 use_sonic: false,
77 use_zero_copy: false, }
79 }
80
81 pub fn zero_copy_optimized() -> Self {
83 Self {
84 sonic: SonicParser::new(),
85 simple: SimpleParser::new(),
86 zero_copy_simd: None, use_sonic: false, use_zero_copy: true,
89 }
90 }
91
92 pub fn parse(&self, input: &[u8]) -> Result<crate::Frame> {
94 if self.use_sonic {
95 match self.sonic.parse(input) {
97 Ok(frame) => Ok(frame),
98 Err(_) => {
99 self.simple.parse(input)
101 }
102 }
103 } else {
104 self.simple.parse(input)
105 }
106 }
107
108 pub fn parse_with_semantics(
110 &self,
111 input: &[u8],
112 semantics: &SemanticMeta,
113 ) -> Result<crate::Frame> {
114 if self.use_sonic {
115 self.simple.parse_with_semantics(input, semantics)
118 } else {
119 self.simple.parse_with_semantics(input, semantics)
120 }
121 }
122
123 pub fn stats(&self) -> ParseStats {
125 if self.use_sonic {
126 ParseStats::default()
128 } else {
129 self.simple.stats()
130 }
131 }
132}
133
134impl Default for Parser {
135 fn default() -> Self {
136 Self::new()
137 }
138}
139
140#[derive(Debug, Clone, Copy, PartialEq)]
142pub enum ValueType {
143 Object,
144 Array,
145 String,
146 Number,
147 Boolean,
148 Null,
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_parser_creation() {
157 let parser = Parser::new();
158 assert_eq!(parser.stats().total_parses, 0);
159 }
160
161 #[test]
162 fn test_simple_parsing() {
163 let parser = Parser::new();
164 let input = br#"{"hello": "world"}"#;
165 let result = parser.parse(input);
166 assert!(result.is_ok());
167
168 let frame = result.unwrap();
169 assert_eq!(frame.payload.len(), input.len());
171 }
172
173 #[test]
174 fn test_numeric_array_parsing() {
175 let parser = Parser::new();
176 let input = b"[1.0, 2.0, 3.0, 4.0]";
177 let result = parser.parse(input);
178 assert!(result.is_ok());
179 }
180
181 #[test]
182 fn test_semantic_parsing() {
183 let parser = Parser::new();
184 let input = b"[1, 2, 3, 4]";
185
186 let semantics = crate::SemanticMeta::new(crate::semantic::SemanticType::NumericArray {
187 dtype: crate::semantic::NumericDType::I32,
188 length: Some(4),
189 });
190
191 let result = parser.parse_with_semantics(input, &semantics);
192 assert!(result.is_ok());
193 }
194
195 #[test]
196 fn test_custom_config() {
197 let config = ParseConfig {
198 detect_semantics: false,
199 max_size_mb: 50,
200 stream_large_arrays: false,
201 stream_threshold: 500,
202 };
203
204 let parser = Parser::with_config(config);
205 let input = br#"{"test": "data"}"#;
206 let result = parser.parse(input);
207 assert!(result.is_ok());
208 }
209}