1mod accumulate;
4mod flat;
5mod keys;
6mod scalar;
7mod scan;
8mod structured;
9
10use crate::error::DecodeError;
11use crate::options::DecodeOptions;
12use crate::structured_scan::scan_structured_keys;
13use crate::value::{Object, Value};
14
15use self::flat::{collect_pair_values, finalize_flat};
16pub(crate) use self::keys::split_key_into_segments;
17use self::scan::parse_query_string_values;
18use self::structured::decode_from_pairs_map;
19
20#[cfg(test)]
21use self::accumulate::combine_with_limit;
22#[cfg(test)]
23use self::flat::{DefaultAccumulator, FlatValues, ParsedFlatValue, value_list_length_for_combine};
24#[cfg(test)]
25use self::keys::{dot_to_bracket_top_level, find_recoverable_balanced_open, parse_keys};
26#[cfg(test)]
27use self::scalar::{
28 decode_component, decode_scalar, interpret_numeric_entities, interpret_numeric_entities_in_node,
29};
30pub fn decode(input: &str, options: &DecodeOptions) -> Result<Object, DecodeError> {
51 options.validate()?;
52
53 if input.is_empty() {
54 return Ok(Object::new());
55 }
56
57 let parsed = parse_query_string_values(input, options)?;
58 if parsed.values.is_empty() {
59 return Ok(Object::new());
60 }
61
62 if !parsed.has_any_structured_syntax {
63 return finalize_flat(parsed.values, options);
64 }
65
66 let structured_scan = scan_structured_keys(parsed.values.key_refs(), options)?;
67 if !structured_scan.has_any_structured_syntax {
68 return finalize_flat(parsed.values, options);
69 }
70
71 decode_from_pairs_map(parsed.values, options, &structured_scan)
72}
73
74pub fn decode_pairs<I>(pairs: I, options: &DecodeOptions) -> Result<Object, DecodeError>
85where
86 I: IntoIterator<Item = (String, Value)>,
87{
88 options.validate()?;
89
90 let parsed = collect_pair_values(pairs, options)?;
91 if parsed.values.is_empty() {
92 return Ok(Object::new());
93 }
94
95 if !parsed.has_any_structured_syntax {
96 return finalize_flat(parsed.values, options);
97 }
98
99 let structured_scan = scan_structured_keys(parsed.values.key_refs(), options)?;
100 if !structured_scan.has_any_structured_syntax {
101 return finalize_flat(parsed.values, options);
102 }
103
104 decode_from_pairs_map(parsed.values, options, &structured_scan)
105}
106
107#[cfg(test)]
108mod tests;