pub struct JSONTools { /* private fields */ }Expand description
Unified JSON Tools API with builder pattern for both flattening and unflattening operations
This is the unified interface for all JSON manipulation operations. It provides a single entry point for all JSON manipulation operations with a consistent builder pattern.
Implementations§
Source§impl JSONTools
impl JSONTools
Sourcepub fn normal(self) -> Self
pub fn normal(self) -> Self
Set the operation mode to normal (apply transformations without flatten/unflatten)
In normal mode, key/value replacements, filtering, and type conversion are applied recursively to the JSON structure without flattening or unflattening it.
§Example
use json_tools_rs::{JSONTools, JsonOutput};
let json = r#"{"Name": "John", "Age": "30", "Active": "true"}"#;
let result = JSONTools::new()
.normal()
.lowercase_keys(true)
.auto_convert_types(true)
.execute(json).unwrap();
match result {
JsonOutput::Single(output) => {
assert!(output.contains(r#""name""#));
assert!(output.contains(r#":30"#) || output.contains(r#": 30"#));
}
_ => unreachable!(),
}Sourcepub fn separator(self, separator: impl Into<String>) -> Self
pub fn separator(self, separator: impl Into<String>) -> Self
Set the separator used for nested keys (default: “.”)
Empty separators are rejected at execute() time with a descriptive error.
Sourcepub fn lowercase_keys(self, value: bool) -> Self
pub fn lowercase_keys(self, value: bool) -> Self
Convert all keys to lowercase
Sourcepub fn key_replacement(
self,
find: impl Into<String>,
replace: impl Into<String>,
) -> Self
pub fn key_replacement( self, find: impl Into<String>, replace: impl Into<String>, ) -> Self
Add a key replacement pattern
Patterns are literal (exact substring match) by default. Wrap a pattern in
r'...' (e.g. r'^admin_') to use standard Rust regex syntax instead. A
malformed r'...' pattern is silently treated as “no match” rather than
raising an error. Works for both flatten and unflatten operations.
§Examples
use json_tools_rs::{JSONTools, JsonOutput};
// Regex pattern, via the r'...' wrapper
let json = r#"{"user_name": "John", "admin_name": "Jane"}"#;
let result = JSONTools::new()
.flatten()
.key_replacement("r'(user|admin)_'", "person_")
.execute(json).unwrap();
// Literal pattern (the default -- no r'...' wrapper)
let result2 = JSONTools::new()
.flatten()
.key_replacement("user_", "person_")
.execute(json).unwrap();Sourcepub fn value_replacement(
self,
find: impl Into<String>,
replace: impl Into<String>,
) -> Self
pub fn value_replacement( self, find: impl Into<String>, replace: impl Into<String>, ) -> Self
Add a value replacement pattern
Patterns are literal (exact substring match) by default. Wrap a pattern in
r'...' (e.g. r'^admin_') to use standard Rust regex syntax instead. A
malformed r'...' pattern is silently treated as “no match” rather than
raising an error. Works for both flatten and unflatten operations.
§Examples
use json_tools_rs::{JSONTools, JsonOutput};
// Regex pattern, via the r'...' wrapper
let json = r#"{"role": "super", "level": "admin"}"#;
let result = JSONTools::new()
.flatten()
.value_replacement("r'^(super|admin)$'", "administrator")
.execute(json).unwrap();
// Literal pattern (the default -- no r'...' wrapper)
let result2 = JSONTools::new()
.flatten()
.value_replacement("@example.com", "@company.org")
.execute(json).unwrap();Sourcepub fn exclude_key(self, pattern: impl Into<String>) -> Self
pub fn exclude_key(self, pattern: impl Into<String>) -> Self
Exclude any key (and its entire value/subtree) whose name contains pattern
Patterns are literal (exact substring match) by default. Wrap a pattern in
r'...' (e.g. r'^crypto_') to use standard Rust regex syntax instead,
matching key_replacement’s convention. Additive – call once per keyword to
exclude multiple.
Checked against the full dot-path in flatten/unflatten mode, and per key at each nesting level in normal mode. Matching a container key drops its entire subtree without walking it – a leaf key is caught by the same check at its own level. Array elements are never matched (no key name to check).
§Examples
use json_tools_rs::{JSONTools, JsonOutput};
// Matching a container key ("crypto_wallet") drops its entire subtree --
// "coin" and "balance" never appear in the output, without being individually
// matched themselves.
let json = r#"{"user": {"name": "John", "crypto_wallet": {"coin": "BTC", "balance": 100}}}"#;
let result = JSONTools::new()
.flatten()
.exclude_key("crypto")
.execute(json).unwrap();
// Output: {"user.name": "John"}Sourcepub fn exclude_value(self, pattern: impl Into<String>) -> Self
pub fn exclude_value(self, pattern: impl Into<String>) -> Self
Drop a key-value pair whose value contains pattern
Patterns are literal (exact substring match) by default. Wrap a pattern in
r'...' to use regex, matching exclude_key’s convention. Additive – call
once per pattern to exclude multiple.
Only ever applies to scalar leaf values (strings/numbers/booleans/null) –
containers have no single value to check, so a value inside a nested object is
still individually checked, but the object itself never is. Checked against the
final value after any configured value_replacement/auto_convert_types
have run, so a value that only matches after being replaced or converted is
still caught – matching remove_nulls’s ordering guarantee. A no-op at the
document root (there’s no parent key to drop the value from).
Unflatten-specific note: string values are matched against their JSON-
serialized form (including surrounding quotes), not the unescaped logical
text. Literal patterns are unaffected by this, but a regex with anchors needs
to account for the quotes, e.g. r'^"admin"$' rather than r'^admin$', to
match a value that’s exactly "admin".
§Examples
use json_tools_rs::{JSONTools, JsonOutput};
let json = r#"{"user": {"name": "John", "status": "banned"}}"#;
let result = JSONTools::new()
.flatten()
.exclude_value("banned")
.execute(json).unwrap();
// Output: {"user.name": "John"}Sourcepub fn remove_empty_strings(self, value: bool) -> Self
pub fn remove_empty_strings(self, value: bool) -> Self
Remove keys with empty string values
Works for both flatten and unflatten operations:
- In flatten mode: removes flattened keys that have empty string values
- In unflatten mode: removes keys from the unflattened JSON structure that have empty string values
Sourcepub fn remove_nulls(self, value: bool) -> Self
pub fn remove_nulls(self, value: bool) -> Self
Remove keys with null values
Works identically in .flatten(), .unflatten(), and .normal() mode, and
for both single-document and batch input:
- In flatten mode: removes flattened keys that have null values
- In unflatten mode: removes keys from the unflattened JSON structure that have null values
- In normal mode: removes keys (at any nesting depth) that have null values
This check runs last in a value’s processing pipeline – after any
configured value_replacement and auto_convert_types have both been
applied – so it reliably catches a null produced by either of those, not
just a null present in the original input. A root-level null (the entire
document, not a nested key) is never removed, since there’s no parent key to
omit it under.
Sourcepub fn remove_empty_objects(self, value: bool) -> Self
pub fn remove_empty_objects(self, value: bool) -> Self
Remove keys with empty object values
Works for both flatten and unflatten operations:
- In flatten mode: removes flattened keys that have empty object values
- In unflatten mode: removes keys from the unflattened JSON structure that have empty object values
Sourcepub fn remove_empty_arrays(self, value: bool) -> Self
pub fn remove_empty_arrays(self, value: bool) -> Self
Remove keys with empty array values
Works for both flatten and unflatten operations:
- In flatten mode: removes flattened keys that have empty array values
- In unflatten mode: removes keys from the unflattened JSON structure that have empty array values
Sourcepub fn handle_key_collision(self, value: bool) -> Self
pub fn handle_key_collision(self, value: bool) -> Self
Handle key collisions by collecting values into arrays
When enabled, collect all values that would have the same key into an array. Works for all operations (flatten, unflatten, normal).
Sourcepub fn auto_convert_types(self, enable: bool) -> Self
pub fn auto_convert_types(self, enable: bool) -> Self
Enable automatic type conversion from strings to dates, nulls, booleans, and numbers
When enabled, the library will attempt to convert string values to their native JSON types:
- Dates: ISO-8601 date/datetime strings are normalized to UTC
- Nulls: “null”/“NULL”/“nil”/“none”/“N/A”/“NA” -> null
- Booleans: “true”/“TRUE”/“True”/“yes”/“on” -> true, “false”/“no”/“off” -> false
- Numbers: “123” -> 123, “1,234.56” -> 1234.56, “$99.99” -> 99.99, “1e5” -> 100000
If conversion fails, the original string value is kept. No errors are thrown.
Works for all operations (flatten, unflatten, normal).
This is equivalent to calling Self::convert_dates, Self::convert_nulls,
Self::convert_booleans, and Self::convert_numbers all with the same
enable value – it only ever flips each category’s on/off switch, preserving
any per-category customization already configured via the convert_*_config
methods. For independent control over each category, or to customize a
category’s behavior (e.g. recognizing extra null tokens, disabling UTC
normalization for dates, or turning off individual number sub-formats like
currency/percent/basis-points/suffixes/fractions/radix), use the convert_*
methods directly instead of this one.
§Example
use json_tools_rs::{JSONTools, JsonOutput};
let json = r#"{"id": "123", "price": "1,234.56", "active": "true"}"#;
let result = JSONTools::new()
.flatten()
.auto_convert_types(true)
.execute(json)
.unwrap();
match result {
JsonOutput::Single(output) => {
// Result: {"id": 123, "price": 1234.56, "active": true}
assert!(output.contains(r#""id":123"#));
assert!(output.contains(r#""price":1234.56"#));
assert!(output.contains(r#""active":true"#));
}
_ => unreachable!(),
}Sourcepub fn convert_dates(self, enable: bool) -> Self
pub fn convert_dates(self, enable: bool) -> Self
Enable or disable date/datetime string conversion independently of the other
type-conversion categories. See Self::auto_convert_types for the general
behavior; use Self::convert_dates_config to customize UTC-normalization
behavior.
§Example
use json_tools_rs::JSONTools;
let tools = JSONTools::new().flatten().convert_dates(true);Sourcepub fn convert_dates_config(self, config: DateConversionConfig) -> Self
pub fn convert_dates_config(self, config: DateConversionConfig) -> Self
Configure date/datetime conversion with custom settings (e.g. disabling UTC
normalization, or disabling the UTC assumption for timezone-less datetimes).
Sets enabled from the passed crate::DateConversionConfig’s own enabled
field.
§Example
use json_tools_rs::{JSONTools, DateConversionConfig};
let tools = JSONTools::new().flatten().convert_dates_config(
DateConversionConfig::new().enabled(true).assume_utc_for_naive(false),
);Sourcepub fn convert_nulls(self, enable: bool) -> Self
pub fn convert_nulls(self, enable: bool) -> Self
Enable or disable null-string conversion independently of the other
type-conversion categories. See Self::auto_convert_types for the general
behavior; use Self::convert_nulls_config to recognize additional tokens.
§Example
use json_tools_rs::JSONTools;
let tools = JSONTools::new().flatten().convert_nulls(true);Sourcepub fn convert_nulls_config(self, config: NullConversionConfig) -> Self
pub fn convert_nulls_config(self, config: NullConversionConfig) -> Self
Configure null-string conversion with additional recognized tokens, beyond the
built-in list. Sets enabled from the passed crate::NullConversionConfig’s
own enabled field.
§Example
use json_tools_rs::{JSONTools, NullConversionConfig};
let tools = JSONTools::new().flatten().convert_nulls_config(
NullConversionConfig::new().enabled(true).add_extra_token("missing"),
);Sourcepub fn convert_booleans(self, enable: bool) -> Self
pub fn convert_booleans(self, enable: bool) -> Self
Enable or disable boolean-string conversion independently of the other
type-conversion categories. See Self::auto_convert_types for the general
behavior; use Self::convert_booleans_config to recognize additional tokens.
§Example
use json_tools_rs::JSONTools;
let tools = JSONTools::new().flatten().convert_booleans(true);Sourcepub fn convert_booleans_config(self, config: BooleanConversionConfig) -> Self
pub fn convert_booleans_config(self, config: BooleanConversionConfig) -> Self
Configure boolean-string conversion with additional recognized true/false
tokens, beyond the built-in lists. Sets enabled from the passed
crate::BooleanConversionConfig’s own enabled field.
§Example
use json_tools_rs::{JSONTools, BooleanConversionConfig};
let tools = JSONTools::new().flatten().convert_booleans_config(
BooleanConversionConfig::new()
.enabled(true)
.add_extra_true_token("si")
.add_extra_false_token("nope"),
);Sourcepub fn convert_numbers(self, enable: bool) -> Self
pub fn convert_numbers(self, enable: bool) -> Self
Enable or disable numeric-string conversion independently of the other
type-conversion categories. See Self::auto_convert_types for the general
behavior; use Self::convert_numbers_config to disable individual
sub-formats (currency, percent, basis points, suffixes, fractions, radix).
§Example
use json_tools_rs::JSONTools;
let tools = JSONTools::new().flatten().convert_numbers(true);Sourcepub fn convert_numbers_config(self, config: NumberConversionConfig) -> Self
pub fn convert_numbers_config(self, config: NumberConversionConfig) -> Self
Configure numeric-string conversion, individually toggling sub-formats.
Plain integers/decimals, scientific notation, and thousands-separator cleanup
are always applied when enabled is true; currency, percent, basis-points,
suffixes, fractions, and radix parsing can each be disabled independently.
Sets enabled from the passed crate::NumberConversionConfig’s own
enabled field.
§Example
use json_tools_rs::{JSONTools, NumberConversionConfig};
let tools = JSONTools::new().flatten().convert_numbers_config(
NumberConversionConfig::new().enabled(true).currency(false),
);Sourcepub fn parallel_threshold(self, threshold: usize) -> Self
pub fn parallel_threshold(self, threshold: usize) -> Self
Set the minimum batch size for parallel processing (only available with ‘parallel’ feature)
When processing multiple JSON documents, this threshold determines when to use parallel processing. Batches smaller than this threshold will be processed sequentially to avoid the overhead of thread spawning.
Default: 100 items (can be overridden with JSON_TOOLS_PARALLEL_THRESHOLD environment variable)
§Arguments
threshold- Minimum number of items in a batch to trigger parallel processing
§Example
use json_tools_rs::JSONTools;
let tools = JSONTools::new()
.flatten()
.parallel_threshold(50); // Only use parallelism for batches of 50+ itemsSourcepub fn num_threads(self, num_threads: Option<usize>) -> Self
pub fn num_threads(self, num_threads: Option<usize>) -> Self
Configure the number of threads for parallel processing
By default, the number of logical CPUs is used. This method allows you to override that behavior for specific workloads or resource constraints.
§Arguments
num_threads- Number of threads to use (None = use system default)
§Examples
use json_tools_rs::JSONTools;
let tools = JSONTools::new()
.flatten()
.num_threads(Some(4)); // Use exactly 4 threadsSourcepub fn nested_parallel_threshold(self, threshold: usize) -> Self
pub fn nested_parallel_threshold(self, threshold: usize) -> Self
Configure the threshold for nested parallel processing within individual JSON documents
When flattening or unflattening a single large JSON document, this threshold determines when to parallelize the processing of objects and arrays. Only objects/arrays with more than this many keys/items will be processed in parallel.
Default: 100 (can be overridden with JSON_TOOLS_NESTED_PARALLEL_THRESHOLD environment variable)
§Arguments
threshold- Minimum number of keys/items to trigger nested parallelism
§Examples
use json_tools_rs::JSONTools;
let tools = JSONTools::new()
.flatten()
.nested_parallel_threshold(200); // Only parallelize objects/arrays with 200+ itemsSourcepub fn max_array_index(self, max: usize) -> Self
pub fn max_array_index(self, max: usize) -> Self
Set the maximum array index allowed during unflattening
This prevents denial-of-service attacks where a malicious flattened key like
"items.999999999" would cause allocation of a massive array. Keys with array
indices exceeding this limit will produce an error during unflattening.
Default: 100,000 (can be overridden with JSON_TOOLS_MAX_ARRAY_INDEX environment variable)
Sourcepub fn execute<'a, T>(
&self,
json_input: T,
) -> Result<JsonOutput, JsonToolsError>
pub fn execute<'a, T>( &self, json_input: T, ) -> Result<JsonOutput, JsonToolsError>
Execute the configured operation on the provided JSON input
This method performs the selected operation based on the mode set by calling
.flatten(), .unflatten(), or .normal(). If no mode was set, an error is returned.
§Arguments
json_input- JSON input that can be a single string, multiple strings, or other supported types
§Returns
Result<JsonOutput, Box<dyn Error>>- The processed JSON result or an error
§Errors
- Returns an error if no operation mode has been set
- Returns an error if the JSON input is invalid
- Returns an error if processing fails for any other reason
Trait Implementations§
Auto Trait Implementations§
impl Freeze for JSONTools
impl RefUnwindSafe for JSONTools
impl Send for JSONTools
impl Sync for JSONTools
impl Unpin for JSONTools
impl UnsafeUnpin for JSONTools
impl UnwindSafe for JSONTools
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more