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