1use std::borrow::Cow;
2use std::collections::HashMap;
3
4use deser_core::Text;
5use deser_core::de::{
6 self, Deserialize, DeserializeDriver, DuplicateKeys, LexicalRules, deserialize_value,
7};
8use deser_core::{Atom, Bytes, ContainerShape, Error, ErrorKind, Event, Source, TrackLocations};
9
10use crate::Nesting;
11use crate::encoding::{Decoded, decode};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct DeserializerConfig {
32 nesting: Nesting,
33 max_depth: usize,
34 max_params: usize,
35
36 context: deser_core::Context,
37}
38
39impl Default for DeserializerConfig {
40 fn default() -> DeserializerConfig {
41 DeserializerConfig::new()
42 }
43}
44
45impl DeserializerConfig {
46 pub const fn new() -> DeserializerConfig {
48 DeserializerConfig {
49 nesting: Nesting::Brackets,
50 max_depth: 16,
51 max_params: 4096,
52
53 context: deser_core::Context::new(),
54 }
55 }
56
57 pub const fn builder() -> DeserializerConfigBuilder {
59 DeserializerConfigBuilder::new()
60 }
61
62 pub const fn into_builder(self) -> DeserializerConfigBuilder {
64 DeserializerConfigBuilder { value: self }
65 }
66
67 pub fn set_context(&mut self, context: deser_core::Context) {
75 self.context = context;
76 }
77
78 pub(crate) fn without_context(&self) -> DeserializerConfig {
81 let mut config = self.clone();
82 config.context = deser_core::Context::default();
83 config
84 }
85
86 pub fn context(&self) -> &deser_core::Context {
88 &self.context
89 }
90
91 pub const fn set_nesting(&mut self, nesting: Nesting) {
97 self.nesting = nesting;
98 }
99
100 pub const fn set_max_depth(&mut self, depth: usize) {
106 self.max_depth = depth;
107 }
108
109 pub const fn set_max_params(&mut self, max: usize) {
114 self.max_params = max;
115 }
116
117 pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
121 deserialize_value(|driver| self.drive_str(s, driver))
122 }
123
124 fn drive_str<'de>(
127 &self,
128 s: &'de str,
129 driver: &mut DeserializeDriver<'_, 'de>,
130 ) -> Result<(), Error> {
131 de::Deserializer::drive(
132 &mut Deserializer::from_str_with_config(s, self.clone()),
133 driver,
134 )
135 }
136
137 pub fn from_slice<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result<T, Error> {
141 deserialize_value(|driver| self.drive_slice(bytes, driver))
142 }
143
144 fn drive_slice<'de>(
147 &self,
148 bytes: &'de [u8],
149 driver: &mut DeserializeDriver<'_, 'de>,
150 ) -> Result<(), Error> {
151 de::Deserializer::drive(
152 &mut Deserializer::from_slice_with_config(bytes, self.clone()),
153 driver,
154 )
155 }
156}
157
158#[derive(Debug, Clone)]
162#[must_use]
163pub struct DeserializerConfigBuilder {
164 value: DeserializerConfig,
165}
166
167impl DeserializerConfigBuilder {
168 pub const fn new() -> DeserializerConfigBuilder {
170 DeserializerConfigBuilder {
171 value: DeserializerConfig::new(),
172 }
173 }
174
175 pub const fn nesting(mut self, nesting: Nesting) -> DeserializerConfigBuilder {
179 self.value.set_nesting(nesting);
180 self
181 }
182
183 pub const fn max_depth(mut self, depth: usize) -> DeserializerConfigBuilder {
187 self.value.set_max_depth(depth);
188 self
189 }
190
191 pub const fn max_params(mut self, max: usize) -> DeserializerConfigBuilder {
195 self.value.set_max_params(max);
196 self
197 }
198
199 pub fn context(mut self, context: deser_core::Context) -> DeserializerConfigBuilder {
203 self.value.set_context(context);
204 self
205 }
206
207 pub const fn build(self) -> DeserializerConfig {
209 let value = unsafe { core::ptr::read(&self.value) };
213 core::mem::forget(self);
214 value
215 }
216}
217
218impl Default for DeserializerConfigBuilder {
219 fn default() -> DeserializerConfigBuilder {
220 DeserializerConfigBuilder::new()
221 }
222}
223
224pub struct Deserializer<'a> {
255 input: &'a str,
256 error: Option<Error>,
258 config: DeserializerConfig,
259}
260
261impl<'a> Deserializer<'a> {
262 #[allow(clippy::should_implement_trait)]
264 pub fn from_str(input: &'a str) -> Deserializer<'a> {
265 Deserializer::from_str_with_config(input, DeserializerConfig::new())
266 }
267
268 pub fn from_str_with_config(input: &'a str, config: DeserializerConfig) -> Deserializer<'a> {
270 Deserializer {
271 input,
272 error: None,
273 config,
274 }
275 }
276
277 pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
282 Deserializer::from_slice_with_config(input, DeserializerConfig::new())
283 }
284
285 pub fn from_slice_with_config(input: &'a [u8], config: DeserializerConfig) -> Deserializer<'a> {
288 match std::str::from_utf8(input) {
289 Ok(input) => Deserializer::from_str_with_config(input, config),
290 Err(err) => Deserializer {
291 input: "",
292 error: Some(Error::with_offset(
293 ErrorKind::Syntax,
294 "input is not valid UTF-8",
295 err.valid_up_to(),
296 )),
297 config,
298 },
299 }
300 }
301
302 pub fn config(&self) -> &DeserializerConfig {
304 &self.config
305 }
306
307 pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
312 de::Deserializer::deserialize(self)
313 }
314
315 pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
320 where
321 T: Deserialize<'a>,
322 F: FnOnce(&mut DeserializeDriver<'_, 'a>),
323 {
324 de::Deserializer::deserialize_with(self, setup)
325 }
326
327 pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
338 if !self.config.context.is_empty() {
339 driver.set_default_context(self.config.context.clone());
340 }
341 if let Some(err) = self.error.take() {
342 return Err(err);
343 }
344 let tree = Tree::parse(self.input, &self.config)?;
345 let state = driver.state_mut();
346 if TrackLocations::of(state) {
347 Source(self.input.into()).set(state);
348 }
349 DuplicateKeys::Last.set_default(state);
352 LexicalRules::LENIENT.set_default(state);
353 tree.emit(driver).map_err(|mut err| {
354 err.resolve_position(self.input.as_bytes());
355 err
356 })
357 }
358}
359
360impl<'a> de::Deserializer<'a> for Deserializer<'a> {
361 fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
362 Deserializer::drive(self, driver)
363 }
364}
365
366type Range = (usize, usize);
368
369enum NodeKey<'a> {
371 Root,
372 Name(Cow<'a, str>),
374 Index(usize, Cow<'a, str>),
376 Push,
378}
379
380struct Node<'a> {
382 key: NodeKey<'a>,
383 key_range: Range,
385 values: Vec<(Decoded<'a>, Range)>,
387 children: Vec<usize>,
389}
390
391enum Container {
393 Map(Vec<usize>),
394 Seq(Vec<usize>),
395}
396
397#[derive(PartialEq, Eq, Hash)]
399enum ChildId<'a> {
400 Name(Cow<'a, str>),
401 Index(usize),
402}
403
404#[derive(Clone, Copy)]
406pub(crate) enum Segment {
407 Name(usize, usize),
408 Index(usize, usize, usize),
409 Push,
410}
411
412struct Tree<'a> {
414 nodes: Vec<Node<'a>>,
415 input_len: usize,
416}
417
418impl<'a> Tree<'a> {
419 fn parse(input: &'a str, config: &DeserializerConfig) -> Result<Tree<'a>, Error> {
420 let mut tree = Tree {
421 nodes: vec![Node {
422 key: NodeKey::Root,
423 key_range: (0, input.len()),
424 values: Vec::new(),
425 children: Vec::new(),
426 }],
427 input_len: input.len(),
428 };
429 let mut lookup = HashMap::new();
430 let mut segments = Vec::new();
431 let mut params = 0;
432 let mut start = usize::from(input.starts_with('?'));
433 while start <= input.len() {
434 let end = input[start..]
435 .find('&')
436 .map_or(input.len(), |pos| start + pos);
437 let pair = &input[start..end];
438 let pair_start = start;
439 start = end + 1;
440 if pair.is_empty() {
441 continue;
442 }
443 params += 1;
444 if params > config.max_params {
445 return Err(Error::with_offset(
446 ErrorKind::LimitExceeded,
447 "too many parameters",
448 pair_start,
449 ));
450 }
451 let (raw_key, raw_value, value_start) = match pair.find('=') {
452 Some(pos) => (&pair[..pos], &pair[pos + 1..], pair_start + pos + 1),
453 None => (pair, "", end),
454 };
455 let key_range = (pair_start, pair_start + raw_key.len());
456 let key = match decode(raw_key) {
457 Decoded::Text(key) => key,
458 Decoded::Bytes(_) => {
459 return Err(Error::with_offset(
460 ErrorKind::Syntax,
461 "key is not valid UTF-8",
462 key_range.0,
463 ));
464 }
465 };
466 let value = decode(raw_value);
467
468 segments.clear();
469 let first = split_key(&key, config.nesting, &mut segments);
470 if segments.len() > config.max_depth {
471 return Err(Error::with_offset(
472 ErrorKind::LimitExceeded,
473 "key is nested too deeply",
474 key_range.0,
475 ));
476 }
477 let mut node = tree.child(&mut lookup, 0, Segment::Name(0, first), &key, key_range);
478 for segment in segments.iter().copied() {
479 node = tree.child(&mut lookup, node, segment, &key, key_range);
480 }
481 tree.nodes[node].values.push((value, (value_start, end)));
482 }
483 Ok(tree)
484 }
485
486 #[allow(clippy::ptr_arg)]
489 fn child(
490 &mut self,
491 lookup: &mut HashMap<(usize, ChildId<'a>), usize>,
492 parent: usize,
493 segment: Segment,
494 key: &Cow<'a, str>,
495 key_range: Range,
496 ) -> usize {
497 let (id, node_key) = match segment {
498 Segment::Name(start, end) => {
499 let name = sub_cow(key, start, end);
500 (Some(ChildId::Name(name.clone())), NodeKey::Name(name))
501 }
502 Segment::Index(index, start, end) => (
503 Some(ChildId::Index(index)),
504 NodeKey::Index(index, sub_cow(key, start, end)),
505 ),
506 Segment::Push => (None, NodeKey::Push),
507 };
508 let id = id.map(|id| (parent, id));
509 if let Some(ref id) = id
510 && let Some(&child) = lookup.get(id)
511 {
512 return child;
513 }
514 let child = self.nodes.len();
515 self.nodes.push(Node {
516 key: node_key,
517 key_range,
518 values: Vec::new(),
519 children: Vec::new(),
520 });
521 self.nodes[parent].children.push(child);
522 if let Some(id) = id {
523 lookup.insert(id, child);
524 }
525 child
526 }
527
528 fn map_shape(&self, children: &[usize]) -> ContainerShape {
533 let len = children
534 .iter()
535 .map(|&child| self.nodes[child].values.len().max(1))
536 .sum();
537 {
538 let mut shape = ContainerShape::with_len(len);
539 shape.set_multimap(true);
540 shape
541 }
542 }
543
544 fn container(&self, node: &Node<'a>) -> Result<Container, Error> {
546 let (mut names, mut indexes, mut pushes) = (false, false, false);
547 for &child in &node.children {
548 match self.nodes[child].key {
549 NodeKey::Name(_) | NodeKey::Root => names = true,
550 NodeKey::Index(..) => indexes = true,
551 NodeKey::Push => pushes = true,
552 }
553 }
554 if pushes && (names || indexes) {
555 return Err(Error::with_offset(
556 ErrorKind::Syntax,
557 "`[]` cannot be combined with other nested keys",
558 node.key_range.0,
559 ));
560 }
561 if pushes {
562 return Ok(Container::Seq(node.children.clone()));
563 }
564 if indexes && !names {
565 let mut sorted = node.children.clone();
567 sorted.sort_by_key(|&child| match self.nodes[child].key {
568 NodeKey::Index(index, _) => index,
569 _ => unreachable!(),
570 });
571 let dense = sorted.iter().enumerate().all(|(pos, &child)| {
572 matches!(self.nodes[child].key, NodeKey::Index(index, _) if index == pos)
573 });
574 if dense {
575 return Ok(Container::Seq(sorted));
576 }
577 }
578 Ok(Container::Map(node.children.clone()))
579 }
580
581 fn emit(&self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
583 struct Frame {
584 children: Vec<usize>,
585 pos: usize,
586 is_map: bool,
587 range: Range,
588 }
589
590 let root = &self.nodes[0];
591 let end = (self.input_len, self.input_len);
592 emit_at(
593 driver,
594 Event::MapStart(self.map_shape(&root.children)),
595 root.key_range,
596 )?;
597 let mut stack = vec![Frame {
598 children: root.children.clone(),
599 pos: 0,
600 is_map: true,
601 range: end,
602 }];
603
604 while let Some(frame) = stack.last_mut() {
605 let Some(&child) = frame.children.get(frame.pos) else {
606 let event = if frame.is_map {
607 Event::MapEnd
608 } else {
609 Event::SeqEnd
610 };
611 let range = frame.range;
612 stack.pop();
613 emit_at(driver, event, range)?;
614 continue;
615 };
616 frame.pos += 1;
617 let is_map = frame.is_map;
618 let node = &self.nodes[child];
619 if is_map {
620 driver
621 .state_mut()
622 .set_input_range(node.key_range.0, node.key_range.1);
623 match node.key {
624 NodeKey::Name(ref name) | NodeKey::Index(_, ref name) => {
625 emit_lexical(driver, name)?
626 }
627 NodeKey::Root | NodeKey::Push => unreachable!(),
628 }
629 }
630
631 match (&node.values[..], node.children.is_empty()) {
632 ([(value, range)], true) => emit_value(driver, value, *range)?,
633 ([(first, first_range), rest @ ..], true) if is_map => {
636 emit_value(driver, first, *first_range)?;
637 for (value, range) in rest {
638 driver
639 .state_mut()
640 .set_input_range(node.key_range.0, node.key_range.1);
641 match node.key {
642 NodeKey::Name(ref name) | NodeKey::Index(_, ref name) => {
643 emit_lexical(driver, name)?
644 }
645 NodeKey::Root | NodeKey::Push => unreachable!(),
646 }
647 emit_value(driver, value, *range)?;
648 }
649 }
650 ([], true) => unreachable!(),
652 (values @ [_, _, ..], true) => {
654 let policy = DuplicateKeys::of(driver.state());
655 let (value, range) = match policy {
656 DuplicateKeys::First => &values[0],
657 DuplicateKeys::Error => {
658 return Err(Error::with_offset(
659 ErrorKind::Syntax,
660 "index given more than once",
661 values[1].1.0,
662 ));
663 }
664 _ => &values[values.len() - 1],
665 };
666 emit_value(driver, value, *range)?;
667 }
668 ([], false) => {
669 let (children, is_map) = match self.container(node)? {
670 Container::Map(children) => (children, true),
671 Container::Seq(children) => (children, false),
672 };
673 let event = if is_map {
674 Event::MapStart(self.map_shape(&children))
675 } else {
676 Event::SeqStart(ContainerShape::with_len(children.len()))
677 };
678 emit_at(driver, event, node.key_range)?;
679 stack.push(Frame {
680 children,
681 pos: 0,
682 is_map,
683 range: node.key_range,
684 });
685 }
686 (_, false) => {
687 return Err(Error::with_offset(
688 ErrorKind::Syntax,
689 "key has a value and nested keys",
690 node.key_range.0,
691 ));
692 }
693 }
694 }
695 Ok(())
696 }
697}
698
699#[inline]
701fn emit_at<'e, E: Into<Event<'e>>>(
702 driver: &mut DeserializeDriver<'_, '_>,
703 event: E,
704 range: Range,
705) -> Result<(), Error> {
706 driver.state_mut().set_input_range(range.0, range.1);
707 driver.emit(event)
708}
709
710#[allow(clippy::ptr_arg)]
713#[inline]
714fn emit_lexical<'a>(
715 driver: &mut DeserializeDriver<'_, 'a>,
716 text: &Cow<'a, str>,
717) -> Result<(), Error> {
718 match *text {
719 Cow::Borrowed(text) => driver.emit_borrowed(Atom::Lexical(Text::borrowed(text))),
720 Cow::Owned(ref text) => driver.emit(Atom::Lexical(Text::borrowed(text.as_str()))),
721 }
722}
723
724fn emit_value<'a>(
726 driver: &mut DeserializeDriver<'_, 'a>,
727 value: &Decoded<'a>,
728 range: Range,
729) -> Result<(), Error> {
730 driver.state_mut().set_input_range(range.0, range.1);
731 match *value {
732 Decoded::Text(ref text) => emit_lexical(driver, text),
733 Decoded::Bytes(ref bytes) => driver.emit(Atom::Bytes(Bytes::borrowed(bytes))),
734 }
735}
736
737fn sub_cow<'a>(key: &Cow<'a, str>, start: usize, end: usize) -> Cow<'a, str> {
739 match *key {
740 Cow::Borrowed(key) => Cow::Borrowed(&key[start..end]),
741 Cow::Owned(ref key) => Cow::Owned(key[start..end].to_string()),
742 }
743}
744
745pub(crate) fn split_key(key: &str, nesting: Nesting, segments: &mut Vec<Segment>) -> usize {
750 let bytes = key.as_bytes();
751 let (open, first_end) = match nesting {
752 Nesting::Flat => return key.len(),
753 Nesting::Brackets => (b'[', bytes.iter().position(|&b| b == b'[')),
754 Nesting::Dots => (b'.', bytes.iter().position(|&b| b == b'.')),
755 };
756 let first_end = match first_end {
757 Some(0) | None => return key.len(),
758 Some(end) => end,
759 };
760 let mut pos = first_end;
761 while pos < bytes.len() {
762 debug_assert_eq!(bytes[pos], open);
763 let (start, end, next) = if open == b'[' {
764 let close = match bytes[pos + 1..].iter().position(|&b| b == b']') {
765 Some(close) => pos + 1 + close,
766 None => break,
767 };
768 (pos + 1, close, close + 1)
769 } else {
770 let end = bytes[pos + 1..]
771 .iter()
772 .position(|&b| b == b'.')
773 .map_or(bytes.len(), |end| pos + 1 + end);
774 (pos + 1, end, end)
775 };
776 let text = &key[start..end];
777 let valid_next = next == bytes.len() || bytes[next] == open;
778 if !valid_next || (open == b'[' && text.contains('[')) || (open == b'.' && text.is_empty())
779 {
780 break;
781 }
782 segments.push(if text.is_empty() {
783 Segment::Push
784 } else if text.bytes().all(|b| b.is_ascii_digit()) {
785 match text.parse() {
786 Ok(index) => Segment::Index(index, start, end),
787 Err(_) => Segment::Name(start, end),
788 }
789 } else {
790 Segment::Name(start, end)
791 });
792 pos = next;
793 }
794 if pos < bytes.len() {
795 segments.clear();
797 return key.len();
798 }
799 first_end
800}
801
802#[cfg(test)]
803fn split(key: &str, nesting: Nesting) -> Vec<String> {
804 let mut segments = Vec::new();
805 let first = split_key(key, nesting, &mut segments);
806 let mut rv = vec![key[..first].to_string()];
807 for segment in segments {
808 rv.push(match segment {
809 Segment::Name(start, end) => key[start..end].to_string(),
810 Segment::Index(index, _, _) => format!("#{}", index),
811 Segment::Push => "[]".to_string(),
812 });
813 }
814 rv
815}
816
817#[test]
818fn test_split_key() {
819 let b = Nesting::Brackets;
820 assert_eq!(split("a", b), ["a"]);
821 assert_eq!(split("a[b][0][]", b), ["a", "b", "#0", "[]"]);
822 assert_eq!(split("a[b.c]", b), ["a", "b.c"]);
823 assert_eq!(split("a[]", b), ["a", "[]"]);
824 assert_eq!(split("a[007]", b), ["a", "#7"]);
825 assert_eq!(
826 split("a[99999999999999999999999]", b),
827 ["a", "99999999999999999999999"]
828 );
829 for key in ["a[b", "[a]", "a[b]c", "a[b[c]]", "a]", "a[b]]"] {
831 assert_eq!(split(key, b), [key], "{}", key);
832 }
833
834 let d = Nesting::Dots;
835 assert_eq!(split("a.b.0", d), ["a", "b", "#0"]);
836 assert_eq!(split("a[b]", d), ["a[b]"]);
837 for key in ["a.", "a..b", ".a"] {
838 assert_eq!(split(key, d), [key], "{}", key);
839 }
840
841 assert_eq!(split("a[b].c", Nesting::Flat), ["a[b].c"]);
842}