1use std::{collections::HashSet, fmt};
27
28pub const MAX_SAFE_INTEGER: i64 = 9_007_199_254_740_991;
30
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub struct Limits {
34 pub max_input_bytes: usize,
35 pub max_depth: usize,
36 pub max_values: usize,
37 pub max_array_items: usize,
38 pub max_object_keys: usize,
39 pub max_string_bytes: usize,
40 pub max_number_bytes: usize,
41 pub max_comments: usize,
42 pub max_comment_bytes: usize,
43 pub max_lines: usize,
44 pub max_line_bytes: usize,
45}
46
47impl Default for Limits {
48 fn default() -> Self {
49 Self {
50 max_input_bytes: 64 * 1024 * 1024,
51 max_depth: 64,
52 max_values: 1_000_000,
53 max_array_items: 250_000,
54 max_object_keys: 256,
55 max_string_bytes: 1024 * 1024,
56 max_number_bytes: 128,
57 max_comments: 100_000,
58 max_comment_bytes: 4 * 1024 * 1024,
59 max_lines: 250_000,
60 max_line_bytes: 1024 * 1024,
61 }
62 }
63}
64
65#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
67pub struct Span {
68 pub start: usize,
69 pub end: usize,
70}
71
72impl Span {
73 #[must_use]
74 pub const fn len(self) -> usize {
75 self.end - self.start
76 }
77
78 #[must_use]
79 pub const fn is_empty(self) -> bool {
80 self.start == self.end
81 }
82}
83
84#[derive(Clone, Debug, PartialEq)]
86pub enum Value {
87 Null { span: Span },
88 Bool { value: bool, span: Span },
89 Integer { value: i64, span: Span },
90 Float { value: f64, span: Span },
91 String { value: String, span: Span },
92 Array { items: Vec<Value>, span: Span },
93 Object { members: Vec<Member>, span: Span },
94}
95
96#[derive(Clone, Debug, PartialEq)]
98pub struct Member {
99 pub key: String,
100 pub key_span: Span,
101 pub value: Value,
102}
103
104#[derive(Clone, Copy, Debug, Eq, PartialEq)]
106pub enum Segment<'a> {
107 Key(&'a str),
108 Index(usize),
109}
110
111impl Value {
112 #[must_use]
113 pub const fn span(&self) -> Span {
114 match self {
115 Self::Null { span }
116 | Self::Bool { span, .. }
117 | Self::Integer { span, .. }
118 | Self::Float { span, .. }
119 | Self::String { span, .. }
120 | Self::Array { span, .. }
121 | Self::Object { span, .. } => *span,
122 }
123 }
124
125 #[must_use]
128 pub const fn kind(&self) -> &'static str {
129 match self {
130 Self::Null { .. } => "null",
131 Self::Bool { .. } => "boolean",
132 Self::Integer { .. } => "integer",
133 Self::Float { .. } => "number",
134 Self::String { .. } => "string",
135 Self::Array { .. } => "array",
136 Self::Object { .. } => "object",
137 }
138 }
139
140 #[must_use]
141 pub const fn as_bool(&self) -> Option<bool> {
142 match self {
143 Self::Bool { value, .. } => Some(*value),
144 _ => None,
145 }
146 }
147
148 #[must_use]
149 pub const fn as_i64(&self) -> Option<i64> {
150 match self {
151 Self::Integer { value, .. } => Some(*value),
152 _ => None,
153 }
154 }
155
156 #[must_use]
158 #[allow(clippy::cast_precision_loss)]
159 pub const fn as_f64(&self) -> Option<f64> {
160 match self {
161 Self::Integer { value, .. } => Some(*value as f64),
162 Self::Float { value, .. } => Some(*value),
163 _ => None,
164 }
165 }
166
167 #[must_use]
168 pub fn as_str(&self) -> Option<&str> {
169 match self {
170 Self::String { value, .. } => Some(value),
171 _ => None,
172 }
173 }
174
175 #[must_use]
176 pub fn as_array(&self) -> Option<&[Value]> {
177 match self {
178 Self::Array { items, .. } => Some(items),
179 _ => None,
180 }
181 }
182
183 #[must_use]
184 pub fn as_object(&self) -> Option<&[Member]> {
185 match self {
186 Self::Object { members, .. } => Some(members),
187 _ => None,
188 }
189 }
190
191 #[must_use]
193 pub fn get(&self, key: &str) -> Option<&Value> {
194 self.as_object()?
195 .iter()
196 .find(|member| member.key == key)
197 .map(|member| &member.value)
198 }
199
200 #[must_use]
202 pub fn member(&self, key: &str) -> Option<&Member> {
203 self.as_object()?.iter().find(|member| member.key == key)
204 }
205
206 #[must_use]
208 pub fn pointer(&self, path: &[Segment<'_>]) -> Option<&Value> {
209 path.iter().try_fold(self, |value, segment| match segment {
210 Segment::Key(key) => value.get(key),
211 Segment::Index(index) => value.as_array()?.get(*index),
212 })
213 }
214}
215
216#[derive(Clone, Debug, PartialEq)]
218pub struct Document {
219 source: String,
220 root: Value,
221}
222
223impl Document {
224 pub fn parse(source: impl Into<String>, limits: &Limits) -> Result<Self, Error> {
229 let source = source.into();
230 let root = parse_value_tree(&source, limits)?;
231 Ok(Self { source, root })
232 }
233
234 #[must_use]
235 pub fn source(&self) -> &str {
236 &self.source
237 }
238
239 #[must_use]
240 pub const fn root(&self) -> &Value {
241 &self.root
242 }
243
244 #[must_use]
249 pub fn text(&self, span: Span) -> &str {
250 &self.source[span.start..span.end]
251 }
252
253 #[must_use]
262 pub fn canonical(&self, value: &Value) -> String {
263 let mut output = String::new();
264 self.write_canonical(value, &mut output);
265 output
266 }
267
268 fn write_canonical(&self, value: &Value, output: &mut String) {
269 match value {
270 Value::Null { .. } => output.push_str("null"),
271 Value::Bool { value, .. } => output.push_str(if *value { "true" } else { "false" }),
272 Value::Integer { span, .. } | Value::Float { span, .. } => {
273 output.push_str(self.text(*span));
274 }
275 Value::String { value, .. } => write_json_string(value, output),
276 Value::Array { items, .. } => {
277 output.push('[');
278 for (index, item) in items.iter().enumerate() {
279 if index > 0 {
280 output.push(',');
281 }
282 self.write_canonical(item, output);
283 }
284 output.push(']');
285 }
286 Value::Object { members, .. } => {
287 output.push('{');
288 for (index, member) in members.iter().enumerate() {
289 if index > 0 {
290 output.push(',');
291 }
292 write_json_string(&member.key, output);
293 output.push(':');
294 self.write_canonical(&member.value, output);
295 }
296 output.push('}');
297 }
298 }
299 }
300
301 pub fn replace(&self, span: Span, text: &str, limits: &Limits) -> Result<Self, Error> {
308 if span.start > span.end
309 || span.end > self.source.len()
310 || !self.source.is_char_boundary(span.start)
311 || !self.source.is_char_boundary(span.end)
312 {
313 return Err(Error {
314 code: ErrorCode::InvalidEdit,
315 offset: span.start.min(self.source.len()),
316 line: 0,
317 column: 0,
318 });
319 }
320 let mut edited = String::with_capacity(self.source.len() - span.len() + text.len());
321 edited.push_str(&self.source[..span.start]);
322 edited.push_str(text);
323 edited.push_str(&self.source[span.end..]);
324 Self::parse(edited, limits)
325 }
326}
327
328#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
330pub enum ErrorCode {
331 InputTooLarge,
332 TooManyLines,
333 LineTooLong,
334 ByteOrderMark,
335 UnexpectedEnd,
336 UnexpectedCharacter,
337 ExpectedValue,
338 ExpectedKey,
339 ExpectedColon,
340 ExpectedCommaOrEnd,
341 TrailingComma,
342 TrailingContent,
343 DuplicateKey,
344 InvalidNumber,
345 NumberTooLong,
346 IntegerOutOfRange,
347 NonFiniteNumber,
348 UnterminatedString,
349 ControlCharacterInString,
350 InvalidEscape,
351 InvalidUnicodeEscape,
352 NulInString,
353 StringTooLong,
354 UnterminatedComment,
355 TooManyComments,
356 DepthLimit,
357 ValueLimit,
358 ArrayLimit,
359 ObjectLimit,
360 InvalidEdit,
361}
362
363impl ErrorCode {
364 #[must_use]
366 pub const fn as_str(self) -> &'static str {
367 match self {
368 Self::InputTooLarge => "jsonc.input_too_large",
369 Self::TooManyLines => "jsonc.too_many_lines",
370 Self::LineTooLong => "jsonc.line_too_long",
371 Self::ByteOrderMark => "jsonc.byte_order_mark",
372 Self::UnexpectedEnd => "jsonc.unexpected_end",
373 Self::UnexpectedCharacter => "jsonc.unexpected_character",
374 Self::ExpectedValue => "jsonc.expected_value",
375 Self::ExpectedKey => "jsonc.expected_key",
376 Self::ExpectedColon => "jsonc.expected_colon",
377 Self::ExpectedCommaOrEnd => "jsonc.expected_comma_or_end",
378 Self::TrailingComma => "jsonc.trailing_comma",
379 Self::TrailingContent => "jsonc.trailing_content",
380 Self::DuplicateKey => "jsonc.duplicate_key",
381 Self::InvalidNumber => "jsonc.invalid_number",
382 Self::NumberTooLong => "jsonc.number_too_long",
383 Self::IntegerOutOfRange => "jsonc.integer_out_of_range",
384 Self::NonFiniteNumber => "jsonc.non_finite_number",
385 Self::UnterminatedString => "jsonc.unterminated_string",
386 Self::ControlCharacterInString => "jsonc.control_character_in_string",
387 Self::InvalidEscape => "jsonc.invalid_escape",
388 Self::InvalidUnicodeEscape => "jsonc.invalid_unicode_escape",
389 Self::NulInString => "jsonc.nul_in_string",
390 Self::StringTooLong => "jsonc.string_too_long",
391 Self::UnterminatedComment => "jsonc.unterminated_comment",
392 Self::TooManyComments => "jsonc.too_many_comments",
393 Self::DepthLimit => "jsonc.depth_limit",
394 Self::ValueLimit => "jsonc.value_limit",
395 Self::ArrayLimit => "jsonc.array_limit",
396 Self::ObjectLimit => "jsonc.object_limit",
397 Self::InvalidEdit => "jsonc.invalid_edit",
398 }
399 }
400}
401
402#[derive(Clone, Copy, Debug, Eq, PartialEq)]
405pub struct Error {
406 pub code: ErrorCode,
407 pub offset: usize,
408 pub line: usize,
409 pub column: usize,
410}
411
412impl fmt::Display for Error {
413 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
414 if self.line == 0 {
415 write!(formatter, "{} at byte {}", self.code.as_str(), self.offset)
416 } else {
417 write!(
418 formatter,
419 "{} at line {}, column {}",
420 self.code.as_str(),
421 self.line,
422 self.column
423 )
424 }
425 }
426}
427
428impl std::error::Error for Error {}
429
430pub fn write_json_string(value: &str, output: &mut String) {
432 use std::fmt::Write as _;
433 output.push('"');
434 for character in value.chars() {
435 match character {
436 '"' => output.push_str("\\\""),
437 '\\' => output.push_str("\\\\"),
438 '\n' => output.push_str("\\n"),
439 '\r' => output.push_str("\\r"),
440 '\t' => output.push_str("\\t"),
441 '\u{8}' => output.push_str("\\b"),
442 '\u{c}' => output.push_str("\\f"),
443 control if u32::from(control) < 0x20 => {
444 let _ = write!(output, "\\u{:04x}", u32::from(control));
445 }
446 other => output.push(other),
447 }
448 }
449 output.push('"');
450}
451
452fn parse_value_tree(source: &str, limits: &Limits) -> Result<Value, Error> {
453 let error_at = |code, offset| Err(locate(source, code, offset));
454 if source.len() > limits.max_input_bytes {
455 return error_at(ErrorCode::InputTooLarge, 0);
456 }
457 if source.starts_with('\u{feff}') {
458 return error_at(ErrorCode::ByteOrderMark, 0);
459 }
460 let mut lines = 1_usize;
461 let mut line_start = 0_usize;
462 for (offset, byte) in source.bytes().enumerate() {
463 if byte == b'\n' {
464 if offset - line_start > limits.max_line_bytes {
465 return error_at(ErrorCode::LineTooLong, line_start);
466 }
467 lines += 1;
468 line_start = offset + 1;
469 if lines > limits.max_lines {
470 return error_at(ErrorCode::TooManyLines, offset);
471 }
472 }
473 }
474 if source.len() - line_start > limits.max_line_bytes {
475 return error_at(ErrorCode::LineTooLong, line_start);
476 }
477 let mut parser = Parser {
478 source,
479 bytes: source.as_bytes(),
480 position: 0,
481 limits,
482 values: 0,
483 comments: 0,
484 comment_bytes: 0,
485 };
486 parser
487 .document()
488 .map_err(|(code, offset)| locate(source, code, offset))
489}
490
491fn locate(source: &str, code: ErrorCode, offset: usize) -> Error {
492 let offset = offset.min(source.len());
493 let mut boundary = offset;
494 while !source.is_char_boundary(boundary) {
495 boundary -= 1;
496 }
497 let before = &source[..boundary];
498 let line = before.bytes().filter(|byte| *byte == b'\n').count() + 1;
499 let line_start = before.rfind('\n').map_or(0, |index| index + 1);
500 let column = source[line_start..boundary].chars().count() + 1;
501 Error {
502 code,
503 offset,
504 line,
505 column,
506 }
507}
508
509type Failure = (ErrorCode, usize);
510
511struct Parser<'a> {
512 source: &'a str,
513 bytes: &'a [u8],
514 position: usize,
515 limits: &'a Limits,
516 values: usize,
517 comments: usize,
518 comment_bytes: usize,
519}
520
521impl Parser<'_> {
522 fn document(&mut self) -> Result<Value, Failure> {
523 self.trivia()?;
524 if self.position == self.bytes.len() {
525 return Err((ErrorCode::ExpectedValue, self.position));
526 }
527 let root = self.value(0)?;
528 self.trivia()?;
529 if self.position != self.bytes.len() {
530 return Err((ErrorCode::TrailingContent, self.position));
531 }
532 Ok(root)
533 }
534
535 fn peek(&self) -> Option<u8> {
536 self.bytes.get(self.position).copied()
537 }
538
539 fn trivia(&mut self) -> Result<(), Failure> {
540 loop {
541 match self.peek() {
542 Some(b' ' | b'\t' | b'\n' | b'\r') => self.position += 1,
543 Some(b'/') => self.comment()?,
544 _ => return Ok(()),
545 }
546 }
547 }
548
549 fn comment(&mut self) -> Result<(), Failure> {
550 let start = self.position;
551 match self.bytes.get(start + 1) {
552 Some(b'/') => {
553 let end = self.bytes[start..]
554 .iter()
555 .position(|byte| *byte == b'\n')
556 .map_or(self.bytes.len(), |index| start + index);
557 self.position = end;
558 }
559 Some(b'*') => {
560 let body = start + 2;
561 let close = self.source[body..]
562 .find("*/")
563 .ok_or((ErrorCode::UnterminatedComment, start))?;
564 self.position = body + close + 2;
565 }
566 _ => return Err((ErrorCode::UnexpectedCharacter, start)),
567 }
568 self.comments += 1;
569 self.comment_bytes += self.position - start;
570 if self.comments > self.limits.max_comments
571 || self.comment_bytes > self.limits.max_comment_bytes
572 {
573 return Err((ErrorCode::TooManyComments, start));
574 }
575 Ok(())
576 }
577
578 fn count_value(&mut self, offset: usize) -> Result<(), Failure> {
579 self.values += 1;
580 if self.values > self.limits.max_values {
581 return Err((ErrorCode::ValueLimit, offset));
582 }
583 Ok(())
584 }
585
586 fn value(&mut self, depth: usize) -> Result<Value, Failure> {
587 let start = self.position;
588 self.count_value(start)?;
589 match self.peek() {
590 None => Err((ErrorCode::UnexpectedEnd, start)),
591 Some(b'{') => self.object(depth + 1),
592 Some(b'[') => self.array(depth + 1),
593 Some(b'"') => {
594 let value = self.string()?;
595 Ok(Value::String {
596 value,
597 span: Span {
598 start,
599 end: self.position,
600 },
601 })
602 }
603 Some(b't') => self.literal(
604 "true",
605 Value::Bool {
606 value: true,
607 span: Span {
608 start,
609 end: start + 4,
610 },
611 },
612 ),
613 Some(b'f') => self.literal(
614 "false",
615 Value::Bool {
616 value: false,
617 span: Span {
618 start,
619 end: start + 5,
620 },
621 },
622 ),
623 Some(b'n') => self.literal(
624 "null",
625 Value::Null {
626 span: Span {
627 start,
628 end: start + 4,
629 },
630 },
631 ),
632 Some(b'-' | b'0'..=b'9') => self.number(),
633 Some(_) => Err((ErrorCode::ExpectedValue, start)),
634 }
635 }
636
637 fn literal(&mut self, word: &str, value: Value) -> Result<Value, Failure> {
638 if self.bytes[self.position..].starts_with(word.as_bytes()) {
639 self.position += word.len();
640 Ok(value)
641 } else {
642 Err((ErrorCode::ExpectedValue, self.position))
643 }
644 }
645
646 fn number(&mut self) -> Result<Value, Failure> {
647 let start = self.position;
648 let mut cursor = start;
649 let digit = |byte: Option<&u8>| matches!(byte, Some(b'0'..=b'9'));
650 if self.bytes.get(cursor) == Some(&b'-') {
651 cursor += 1;
652 }
653 match self.bytes.get(cursor) {
654 Some(b'0') => cursor += 1,
655 Some(b'1'..=b'9') => {
656 while digit(self.bytes.get(cursor)) {
657 cursor += 1;
658 }
659 }
660 _ => return Err((ErrorCode::InvalidNumber, start)),
661 }
662 let mut integer = true;
663 if self.bytes.get(cursor) == Some(&b'.') {
664 integer = false;
665 cursor += 1;
666 if !digit(self.bytes.get(cursor)) {
667 return Err((ErrorCode::InvalidNumber, start));
668 }
669 while digit(self.bytes.get(cursor)) {
670 cursor += 1;
671 }
672 }
673 if matches!(self.bytes.get(cursor), Some(b'e' | b'E')) {
674 integer = false;
675 cursor += 1;
676 if matches!(self.bytes.get(cursor), Some(b'+' | b'-')) {
677 cursor += 1;
678 }
679 if !digit(self.bytes.get(cursor)) {
680 return Err((ErrorCode::InvalidNumber, start));
681 }
682 while digit(self.bytes.get(cursor)) {
683 cursor += 1;
684 }
685 }
686 if matches!(
687 self.bytes.get(cursor),
688 Some(b'0'..=b'9' | b'.' | b'e' | b'E' | b'+' | b'-' | b'x' | b'X')
689 ) {
690 return Err((ErrorCode::InvalidNumber, start));
691 }
692 if cursor - start > self.limits.max_number_bytes {
693 return Err((ErrorCode::NumberTooLong, start));
694 }
695 let text = &self.source[start..cursor];
696 let span = Span { start, end: cursor };
697 self.position = cursor;
698 if integer {
699 let value = text
700 .parse::<i64>()
701 .map_err(|_| (ErrorCode::IntegerOutOfRange, start))?;
702 if !(-MAX_SAFE_INTEGER..=MAX_SAFE_INTEGER).contains(&value) {
703 return Err((ErrorCode::IntegerOutOfRange, start));
704 }
705 Ok(Value::Integer { value, span })
706 } else {
707 let value = text
708 .parse::<f64>()
709 .map_err(|_| (ErrorCode::InvalidNumber, start))?;
710 if !value.is_finite() {
711 return Err((ErrorCode::NonFiniteNumber, start));
712 }
713 Ok(Value::Float { value, span })
714 }
715 }
716
717 fn string(&mut self) -> Result<String, Failure> {
718 let start = self.position;
719 self.position += 1;
720 let mut value = String::new();
721 loop {
722 let run_start = self.position;
723 while let Some(byte) = self.peek() {
724 if byte == b'"' || byte == b'\\' || byte < 0x20 {
725 break;
726 }
727 self.position += 1;
728 }
729 value.push_str(&self.source[run_start..self.position]);
730 if value.len() > self.limits.max_string_bytes {
731 return Err((ErrorCode::StringTooLong, start));
732 }
733 match self.peek() {
734 None => return Err((ErrorCode::UnterminatedString, start)),
735 Some(b'"') => {
736 self.position += 1;
737 return Ok(value);
738 }
739 Some(b'\\') => {
740 let escaped = self.escape()?;
741 if escaped == '\0' {
742 return Err((ErrorCode::NulInString, self.position));
743 }
744 value.push(escaped);
745 if value.len() > self.limits.max_string_bytes {
746 return Err((ErrorCode::StringTooLong, start));
747 }
748 }
749 Some(_) => return Err((ErrorCode::ControlCharacterInString, self.position)),
750 }
751 }
752 }
753
754 fn escape(&mut self) -> Result<char, Failure> {
755 let start = self.position;
756 let kind = self
757 .bytes
758 .get(start + 1)
759 .copied()
760 .ok_or((ErrorCode::UnterminatedString, start))?;
761 self.position += 2;
762 Ok(match kind {
763 b'"' => '"',
764 b'\\' => '\\',
765 b'/' => '/',
766 b'b' => '\u{8}',
767 b'f' => '\u{c}',
768 b'n' => '\n',
769 b'r' => '\r',
770 b't' => '\t',
771 b'u' => {
772 let first = self.hex4(start)?;
773 match first {
774 0xd800..=0xdbff => {
775 if self.bytes.get(self.position) != Some(&b'\\')
776 || self.bytes.get(self.position + 1) != Some(&b'u')
777 {
778 return Err((ErrorCode::InvalidUnicodeEscape, start));
779 }
780 self.position += 2;
781 let second = self.hex4(start)?;
782 if !(0xdc00..=0xdfff).contains(&second) {
783 return Err((ErrorCode::InvalidUnicodeEscape, start));
784 }
785 let scalar = 0x1_0000 + ((first - 0xd800) << 10) + (second - 0xdc00);
786 char::from_u32(scalar).ok_or((ErrorCode::InvalidUnicodeEscape, start))?
787 }
788 0xdc00..=0xdfff => return Err((ErrorCode::InvalidUnicodeEscape, start)),
789 scalar => {
790 char::from_u32(scalar).ok_or((ErrorCode::InvalidUnicodeEscape, start))?
791 }
792 }
793 }
794 _ => return Err((ErrorCode::InvalidEscape, start)),
795 })
796 }
797
798 fn hex4(&mut self, escape_start: usize) -> Result<u32, Failure> {
799 let digits = self
800 .bytes
801 .get(self.position..self.position + 4)
802 .ok_or((ErrorCode::InvalidUnicodeEscape, escape_start))?;
803 let mut value = 0_u32;
804 for digit in digits {
805 let nibble = char::from(*digit)
806 .to_digit(16)
807 .ok_or((ErrorCode::InvalidUnicodeEscape, escape_start))?;
808 value = value * 16 + nibble;
809 }
810 self.position += 4;
811 Ok(value)
812 }
813
814 fn array(&mut self, depth: usize) -> Result<Value, Failure> {
815 let start = self.position;
816 if depth > self.limits.max_depth {
817 return Err((ErrorCode::DepthLimit, start));
818 }
819 self.position += 1;
820 let mut items = Vec::new();
821 self.trivia()?;
822 if self.peek() == Some(b']') {
823 self.position += 1;
824 return Ok(Value::Array {
825 items,
826 span: Span {
827 start,
828 end: self.position,
829 },
830 });
831 }
832 loop {
833 self.trivia()?;
834 if items.len() == self.limits.max_array_items {
835 return Err((ErrorCode::ArrayLimit, self.position));
836 }
837 items.push(self.value(depth)?);
838 self.trivia()?;
839 match self.peek() {
840 Some(b',') => {
841 let comma = self.position;
842 self.position += 1;
843 self.trivia()?;
844 if self.peek() == Some(b']') {
845 return Err((ErrorCode::TrailingComma, comma));
846 }
847 }
848 Some(b']') => {
849 self.position += 1;
850 return Ok(Value::Array {
851 items,
852 span: Span {
853 start,
854 end: self.position,
855 },
856 });
857 }
858 None => return Err((ErrorCode::UnexpectedEnd, self.position)),
859 Some(_) => return Err((ErrorCode::ExpectedCommaOrEnd, self.position)),
860 }
861 }
862 }
863
864 fn object(&mut self, depth: usize) -> Result<Value, Failure> {
865 let start = self.position;
866 if depth > self.limits.max_depth {
867 return Err((ErrorCode::DepthLimit, start));
868 }
869 self.position += 1;
870 let mut members: Vec<Member> = Vec::new();
871 let mut keys = HashSet::new();
872 self.trivia()?;
873 if self.peek() == Some(b'}') {
874 self.position += 1;
875 return Ok(Value::Object {
876 members,
877 span: Span {
878 start,
879 end: self.position,
880 },
881 });
882 }
883 loop {
884 self.trivia()?;
885 let key_start = self.position;
886 match self.peek() {
887 Some(b'"') => {}
888 None => return Err((ErrorCode::UnexpectedEnd, key_start)),
889 Some(_) => return Err((ErrorCode::ExpectedKey, key_start)),
890 }
891 if members.len() == self.limits.max_object_keys {
892 return Err((ErrorCode::ObjectLimit, key_start));
893 }
894 let key = self.string()?;
895 let key_span = Span {
896 start: key_start,
897 end: self.position,
898 };
899 if !keys.insert(key.clone()) {
900 return Err((ErrorCode::DuplicateKey, key_start));
901 }
902 self.trivia()?;
903 if self.peek() != Some(b':') {
904 return Err((ErrorCode::ExpectedColon, self.position));
905 }
906 self.position += 1;
907 self.trivia()?;
908 let value = self.value(depth)?;
909 members.push(Member {
910 key,
911 key_span,
912 value,
913 });
914 self.trivia()?;
915 match self.peek() {
916 Some(b',') => {
917 let comma = self.position;
918 self.position += 1;
919 self.trivia()?;
920 if self.peek() == Some(b'}') {
921 return Err((ErrorCode::TrailingComma, comma));
922 }
923 }
924 Some(b'}') => {
925 self.position += 1;
926 return Ok(Value::Object {
927 members,
928 span: Span {
929 start,
930 end: self.position,
931 },
932 });
933 }
934 None => return Err((ErrorCode::UnexpectedEnd, self.position)),
935 Some(_) => return Err((ErrorCode::ExpectedCommaOrEnd, self.position)),
936 }
937 }
938 }
939}
940
941#[cfg(test)]
942mod tests;