Enum jomini::json::DuplicateKeyMode
source · pub enum DuplicateKeyMode {
Group,
Preserve,
KeyValuePairs,
}
Expand description
Controls JSON structure when duplicate keys are encountered
It’s debatable whether duplicate keys is valid JSON, so this allows one to customize output depending how flexible a downstream client is at handling JSON.
The options are either:
- Group values into an array under a single field
- Preserve the duplicate keys
- Rewrite objects as an array of key value pairs
Variants§
Group
Group values into an array under a single field
use jomini::{TextTape, json::{JsonOptions, DuplicateKeyMode}};
let tape = TextTape::from_slice(b"a={b=1} c={b=1 b=2}")?;
let reader = tape.windows1252_reader();
let options = JsonOptions::new()
.with_duplicate_keys(DuplicateKeyMode::Group);
let actual = reader.json()
.with_options(options)
.to_string();
assert_eq!(actual, r#"{"a":{"b":1},"c":{"b":[1,2]}}"#);
As shown above, downstream clients will need to be flexible enough to handle grouped and ungrouped keys, and may prove cumbersome or challenging to leverage automatic deserialization logic. Python or Javascript clients may like this output due to their more dynamic typing nature.
Grouping keys together will have a small but measurable impact on performance
Preserve
Preserve the duplicate keys (the default behavior)
use jomini::{TextTape, json::{JsonOptions, DuplicateKeyMode}};
let tape = TextTape::from_slice(b"a={b=1} c={b=1 b=2}")?;
let reader = tape.windows1252_reader();
let actual = reader.json()
.with_options(JsonOptions::new())
.to_string();
assert_eq!(actual, r#"{"a":{"b":1},"c":{"b":1,"b":2}}"#);
Preserving duplicate keys is the default mode as it represents the most concise output and most closely matches the input.
Insertion order of an object’s keys are maintained.
Python and Javascript clients may not like this output as their builtin JSON modules don’t handle duplicate keys well. However, lower level JSON parsers like simd-json tend to handle duplicate keys just fine.
KeyValuePairs
Rewrite objects as an array of 2 element arrays (the key and the value).
use jomini::{TextTape, json::{JsonOptions, DuplicateKeyMode}};
let tape = TextTape::from_slice(b"c=0 b={1 2}")?;
let reader = tape.windows1252_reader();
let options = JsonOptions::new()
.with_duplicate_keys(DuplicateKeyMode::KeyValuePairs);
let actual = reader.json()
.with_options(options)
.to_string();
assert_eq!(actual, r#"{"type":"obj","val":[["c",0],["b",{"type":"array","val":[1,2]}]]}"#);
Objects and arrays are now transformed into adjacently tagged objects
(to borrow a term from
serde).
Objects have a type of obj
and arrays have a type of array
. This
adjacently tagged object is needed to disambiguate between objects and
arrays if both are going to be represented with JSON arrays.
This output has the largest departure from the input and is the most verbose, but it allows one to use inflexible DOM parsers like those seen in Python and Javascript and still maintain the positioning of duplicate keys. Preserving positioning is important when interpretting an object is dependant on the order of the keys and duplicate keys may affect subsequent fields.
Trait Implementations§
source§impl Clone for DuplicateKeyMode
impl Clone for DuplicateKeyMode
source§fn clone(&self) -> DuplicateKeyMode
fn clone(&self) -> DuplicateKeyMode
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Debug for DuplicateKeyMode
impl Debug for DuplicateKeyMode
source§impl PartialEq for DuplicateKeyMode
impl PartialEq for DuplicateKeyMode
source§fn eq(&self, other: &DuplicateKeyMode) -> bool
fn eq(&self, other: &DuplicateKeyMode) -> bool
self
and other
values to be equal, and is used
by ==
.