tool_parser/
partial_json.rs1use serde_json::{Map, Value};
2
3use crate::{
4 errors::{ParserError, ParserResult},
5 parsers::helpers::is_complete_json,
6 traits::PartialJsonParser,
7};
8
9pub struct PartialJson {
11 max_depth: usize,
13 allow_incomplete: bool,
15}
16
17impl PartialJson {
18 pub fn new(max_depth: usize, allow_incomplete: bool) -> Self {
20 Self {
21 max_depth,
22 allow_incomplete,
23 }
24 }
25
26 pub fn parse_value(
33 &self,
34 input: &str,
35 allow_partial_strings: bool,
36 ) -> ParserResult<(Value, usize)> {
37 let mut parser = Parser::new(
38 input,
39 self.max_depth,
40 self.allow_incomplete,
41 allow_partial_strings,
42 );
43 let value = parser.parse_value(0)?;
44 Ok((value, parser.position))
45 }
46}
47
48impl Default for PartialJson {
49 fn default() -> Self {
50 Self::new(32, true)
51 }
52}
53
54impl PartialJsonParser for PartialJson {
55 fn parse(&self, input: &str) -> ParserResult<(Value, usize)> {
56 self.parse_value(input, true)
58 }
59
60 fn is_complete(&self, input: &str) -> bool {
61 is_complete_json(input)
62 }
63
64 fn max_depth(&self) -> usize {
65 self.max_depth
66 }
67}
68
69struct Parser<'a> {
71 chars: std::iter::Peekable<std::str::Chars<'a>>,
72 position: usize,
73 max_depth: usize,
74 allow_incomplete: bool,
75 allow_partial_strings: bool,
76}
77
78impl<'a> Parser<'a> {
79 fn new(
80 input: &'a str,
81 max_depth: usize,
82 allow_incomplete: bool,
83 allow_partial_strings: bool,
84 ) -> Self {
85 Self {
86 chars: input.chars().peekable(),
87 position: 0,
88 max_depth,
89 allow_incomplete,
90 allow_partial_strings,
91 }
92 }
93
94 fn peek(&mut self) -> Option<char> {
95 self.chars.peek().copied()
96 }
97
98 fn advance(&mut self) {
99 if let Some(c) = self.chars.next() {
100 self.position += c.len_utf8();
101 }
102 }
103
104 fn skip_whitespace(&mut self) {
105 while let Some(ch) = self.peek() {
106 if ch.is_whitespace() {
107 self.advance();
108 } else {
109 break;
110 }
111 }
112 }
113
114 fn parse_value(&mut self, depth: usize) -> ParserResult<Value> {
115 if depth > self.max_depth {
116 return Err(ParserError::DepthExceeded(self.max_depth));
117 }
118
119 self.skip_whitespace();
120
121 match self.peek() {
122 Some('{') => self.parse_object(depth + 1),
123 Some('[') => self.parse_array(depth + 1),
124 Some('"') => self.parse_string(),
125 Some('t') | Some('f') => self.parse_bool(),
126 Some('n') => self.parse_null(),
127 Some(c) if c == '-' || c.is_ascii_digit() => self.parse_number(),
128 _ => {
129 if self.allow_incomplete {
130 Ok(Value::Null)
131 } else {
132 Err(ParserError::ParsingFailed("Unexpected character".into()))
133 }
134 }
135 }
136 }
137
138 fn parse_object(&mut self, depth: usize) -> ParserResult<Value> {
139 if depth > self.max_depth {
140 return Err(ParserError::DepthExceeded(self.max_depth));
141 }
142
143 let mut object = Map::new();
144
145 self.advance();
147 self.skip_whitespace();
148
149 if self.peek() == Some('}') {
151 self.advance();
152 return Ok(Value::Object(object));
153 }
154
155 loop {
156 let key = match self.parse_string() {
158 Ok(Value::String(s)) => s,
159 Err(_) if self.allow_incomplete => {
160 return Ok(Value::Object(object));
162 }
163 Err(e) => return Err(e),
164 _ => return Err(ParserError::ParsingFailed("Expected string key".into())),
165 };
166
167 self.skip_whitespace();
168
169 if self.peek() != Some(':') {
171 if self.allow_incomplete {
172 object.insert(key, Value::Null);
174 return Ok(Value::Object(object));
175 }
176 return Err(ParserError::ParsingFailed("Expected ':'".into()));
177 }
178 self.advance();
179 self.skip_whitespace();
180
181 let value = match self.parse_value(depth) {
183 Ok(v) => v,
184 Err(_) if self.allow_incomplete => {
185 if self.allow_partial_strings {
189 object.insert(key, Value::Null);
191 }
192 return Ok(Value::Object(object));
193 }
194 Err(e) => return Err(e),
195 };
196
197 object.insert(key, value);
198 self.skip_whitespace();
199
200 match self.peek() {
201 Some(',') => {
202 self.advance();
203 self.skip_whitespace();
204 if self.peek() == Some('}') {
206 self.advance();
207 return Ok(Value::Object(object));
208 }
209 }
210 Some('}') => {
211 self.advance();
212 return Ok(Value::Object(object));
213 }
214 None if self.allow_incomplete => {
215 return Ok(Value::Object(object));
216 }
217 _ => {
218 if self.allow_incomplete {
219 return Ok(Value::Object(object));
220 }
221 return Err(ParserError::ParsingFailed("Expected ',' or '}'".into()));
222 }
223 }
224 }
225 }
226
227 fn parse_array(&mut self, depth: usize) -> ParserResult<Value> {
228 if depth > self.max_depth {
229 return Err(ParserError::DepthExceeded(self.max_depth));
230 }
231
232 let mut array = Vec::new();
233
234 self.advance();
236 self.skip_whitespace();
237
238 if self.peek() == Some(']') {
240 self.advance();
241 return Ok(Value::Array(array));
242 }
243
244 loop {
245 let value = match self.parse_value(depth) {
247 Ok(v) => v,
248 Err(_) if self.allow_incomplete => {
249 return Ok(Value::Array(array));
250 }
251 Err(e) => return Err(e),
252 };
253
254 array.push(value);
255 self.skip_whitespace();
256
257 match self.peek() {
258 Some(',') => {
259 self.advance();
260 self.skip_whitespace();
261 if self.peek() == Some(']') {
263 self.advance();
264 return Ok(Value::Array(array));
265 }
266 }
267 Some(']') => {
268 self.advance();
269 return Ok(Value::Array(array));
270 }
271 None if self.allow_incomplete => {
272 return Ok(Value::Array(array));
273 }
274 _ => {
275 if self.allow_incomplete {
276 return Ok(Value::Array(array));
277 }
278 return Err(ParserError::ParsingFailed("Expected ',' or ']'".into()));
279 }
280 }
281 }
282 }
283
284 fn parse_string(&mut self) -> ParserResult<Value> {
285 if self.peek() != Some('"') {
286 return Err(ParserError::ParsingFailed("Expected '\"'".into()));
287 }
288
289 self.advance();
291
292 let mut string = String::new();
293 let mut escaped = false;
294
295 while let Some(ch) = self.peek() {
296 if escaped {
297 let escaped_char = match ch {
299 '"' | '\\' | '/' => ch,
300 'b' => '\u{0008}',
301 'f' => '\u{000C}',
302 'n' => '\n',
303 'r' => '\r',
304 't' => '\t',
305 'u' => {
306 self.advance();
308 let hex = self.parse_unicode_escape()?;
309 string.push(hex);
310 escaped = false;
311 continue;
312 }
313 _ => ch, };
315 string.push(escaped_char);
316 escaped = false;
317 } else if ch == '\\' {
318 escaped = true;
319 } else if ch == '"' {
320 self.advance();
322 return Ok(Value::String(string));
323 } else {
324 string.push(ch);
325 }
326 self.advance();
327 }
328
329 if self.allow_incomplete && self.allow_partial_strings {
331 Ok(Value::String(string))
332 } else {
333 Err(ParserError::ParsingFailed("Unterminated string".into()))
334 }
335 }
336
337 fn parse_unicode_escape(&mut self) -> ParserResult<char> {
338 let mut hex = String::new();
339 for _ in 0..4 {
340 if let Some(ch) = self.peek() {
341 if ch.is_ascii_hexdigit() {
342 hex.push(ch);
343 self.advance();
344 } else {
345 break;
346 }
347 } else {
348 break;
349 }
350 }
351
352 if hex.len() == 4 {
353 let mut code = u32::from_str_radix(&hex, 16)
354 .map_err(|_| ParserError::ParsingFailed("Invalid unicode escape".into()))?;
355 if (0xD800..=0xDBFF).contains(&code) {
357 let mut ahead = self.chars.clone();
358 if ahead.next() == Some('\\') && ahead.next() == Some('u') {
359 let low: String = ahead.take(4).collect();
360 if let Ok(low @ 0xDC00..=0xDFFF) = u32::from_str_radix(&low, 16) {
361 code = 0x10000 + ((code - 0xD800) << 10) + (low - 0xDC00);
362 (0..6).for_each(|_| self.advance());
363 }
364 }
365 }
366 char::from_u32(code)
367 .ok_or_else(|| ParserError::ParsingFailed("Invalid unicode escape".into()))
368 } else if self.allow_incomplete {
369 Ok('\u{FFFD}') } else {
371 Err(ParserError::ParsingFailed(
372 "Incomplete unicode escape".into(),
373 ))
374 }
375 }
376
377 fn parse_number(&mut self) -> ParserResult<Value> {
378 let mut number = String::new();
379
380 if self.peek() == Some('-') {
382 number.push('-');
383 self.advance();
384 }
385
386 if self.peek() == Some('0') {
388 number.push('0');
389 self.advance();
390 } else {
391 while let Some(ch) = self.peek() {
392 if ch.is_ascii_digit() {
393 number.push(ch);
394 self.advance();
395 } else {
396 break;
397 }
398 }
399 }
400
401 if self.peek() == Some('.') {
403 number.push('.');
404 self.advance();
405
406 while let Some(ch) = self.peek() {
407 if ch.is_ascii_digit() {
408 number.push(ch);
409 self.advance();
410 } else {
411 break;
412 }
413 }
414 }
415
416 if let Some(ch) = self.peek() {
418 if ch == 'e' || ch == 'E' {
419 number.push(ch);
420 self.advance();
421
422 if let Some(sign) = self.peek() {
423 if sign == '+' || sign == '-' {
424 number.push(sign);
425 self.advance();
426 }
427 }
428
429 while let Some(ch) = self.peek() {
430 if ch.is_ascii_digit() {
431 number.push(ch);
432 self.advance();
433 } else {
434 break;
435 }
436 }
437 }
438 }
439
440 if let Ok(n) = number.parse::<i64>() {
442 Ok(Value::Number(serde_json::Number::from(n)))
443 } else if let Ok(n) = number.parse::<f64>() {
444 Ok(Value::Number(
445 serde_json::Number::from_f64(n).unwrap_or_else(|| serde_json::Number::from(0)),
446 ))
447 } else if self.allow_incomplete {
448 Ok(Value::Number(serde_json::Number::from(0)))
449 } else {
450 Err(ParserError::ParsingFailed("Invalid number".into()))
451 }
452 }
453
454 fn parse_bool(&mut self) -> ParserResult<Value> {
455 let mut word = String::new();
456
457 let mut temp_chars = self.chars.clone();
459 while let Some(&ch) = temp_chars.peek() {
460 if ch.is_alphabetic() && word.len() < 5 {
461 word.push(ch);
463 temp_chars.next();
464 } else {
465 break;
466 }
467 }
468
469 let is_valid = word == "true"
471 || word == "false"
472 || (self.allow_incomplete && ("true".starts_with(&word) || "false".starts_with(&word)));
473
474 if !is_valid {
475 return Err(ParserError::ParsingFailed("Invalid boolean".into()));
476 }
477
478 word.clear();
480 while let Some(ch) = self.peek() {
481 if ch.is_alphabetic() {
482 word.push(ch);
483 self.advance();
484 } else {
485 break;
486 }
487 }
488
489 match word.as_str() {
490 "true" => Ok(Value::Bool(true)),
491 "false" => Ok(Value::Bool(false)),
492 partial if self.allow_incomplete => {
493 if "true".starts_with(partial) {
494 Ok(Value::Bool(true))
495 } else if "false".starts_with(partial) {
496 Ok(Value::Bool(false))
497 } else {
498 Err(ParserError::ParsingFailed("Invalid boolean".into()))
499 }
500 }
501 _ => Err(ParserError::ParsingFailed("Invalid boolean".into())),
502 }
503 }
504
505 fn parse_null(&mut self) -> ParserResult<Value> {
506 let mut word = String::new();
507
508 let mut temp_chars = self.chars.clone();
510 while let Some(&ch) = temp_chars.peek() {
511 if ch.is_alphabetic() && word.len() < 4 {
512 word.push(ch);
514 temp_chars.next();
515 } else {
516 break;
517 }
518 }
519
520 let is_valid = word == "null" || (self.allow_incomplete && "null".starts_with(&word));
522
523 if !is_valid {
524 return Err(ParserError::ParsingFailed("Invalid null".into()));
525 }
526
527 word.clear();
529 while let Some(ch) = self.peek() {
530 if ch.is_alphabetic() {
531 word.push(ch);
532 self.advance();
533 } else {
534 break;
535 }
536 }
537
538 if word == "null" || (self.allow_incomplete && "null".starts_with(&word)) {
539 Ok(Value::Null)
540 } else {
541 Err(ParserError::ParsingFailed("Invalid null".into()))
542 }
543 }
544}