Expand description
§JSON Tools RS
A Rust library for advanced JSON manipulation, including flattening and unflattening nested JSON structures with configurable filtering and replacement options.
§Features
- Unified API: Single
JSONToolsentry point for both flattening and unflattening - Builder Pattern: Fluent, chainable API for easy configuration
- Advanced Filtering: Remove empty values (strings, objects, arrays, null values)
- Pattern Replacements: Support for literal and regex-based key/value replacements
- High Performance: SIMD-accelerated JSON parsing with optimized algorithms
- Batch Processing: Handle single JSON strings or arrays of JSON strings
- Comprehensive Error Handling: Detailed error messages for debugging
§Notes
- Root-level empty arrays: Flattening an empty array (
[]) produces"{}"(an empty object), because flattening always yields key-value pairs. Zero elements means zero key-value pairs, which is represented as an empty object.
§Quick Start with Unified API
§Flattening JSON
use json_tools_rs::{JSONTools, JsonOutput};
let json = r#"{"user": {"name": "John", "details": {"age": null, "city": ""}}}"#;
let result = JSONTools::new()
.flatten()
.separator("::")
.lowercase_keys(true)
.key_replacement("r'(User|Admin)_'", "")
.value_replacement("@example.com", "@company.org")
.remove_empty_strings(true)
.remove_nulls(true)
.remove_empty_objects(true)
.remove_empty_arrays(true)
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"user::name": "John"}
println!("{}", flattened);
}
JsonOutput::Multiple(_) => unreachable!(),
}§Unflattening JSON
use json_tools_rs::{JSONTools, JsonOutput};
let flattened = r#"{"user::name": "John", "user::age": 30}"#;
let result = JSONTools::new()
.unflatten()
.separator("::")
.lowercase_keys(true)
.key_replacement("r'(User|Admin)_'", "")
.value_replacement("@company.org", "@example.com")
.remove_empty_strings(true)
.remove_nulls(true)
.remove_empty_objects(true)
.remove_empty_arrays(true)
.execute(flattened).unwrap();
match result {
JsonOutput::Single(unflattened) => {
// Result: {"user": {"name": "John", "age": 30}}
println!("{}", unflattened);
}
JsonOutput::Multiple(_) => unreachable!(),
}§Doctests
The following doctests demonstrate individual features in a progressive learning format. Each example focuses on a specific capability to help users understand how to use the library effectively.
§1. Basic Flattening and Unflattening Operations
use json_tools_rs::{JSONTools, JsonOutput};
// Basic flattening - converts nested JSON to flat key-value pairs
let nested_json = r#"{"user": {"name": "John", "profile": {"age": 30}}}"#;
let result = JSONTools::new()
.flatten()
.execute(nested_json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"user.name": "John", "user.profile.age": 30}
assert!(flattened.contains("user.name"));
assert!(flattened.contains("user.profile.age"));
}
JsonOutput::Multiple(_) => unreachable!(),
}
// Basic unflattening - converts flat JSON back to nested structure
let flat_json = r#"{"user.name": "John", "user.profile.age": 30}"#;
let result = JSONTools::new()
.unflatten()
.execute(flat_json).unwrap();
match result {
JsonOutput::Single(unflattened) => {
// Result: {"user": {"name": "John", "profile": {"age": 30}}}
assert!(unflattened.contains(r#""user""#));
assert!(unflattened.contains(r#""name":"John""#));
}
JsonOutput::Multiple(_) => unreachable!(),
}§2. Custom Separator Usage
use json_tools_rs::{JSONTools, JsonOutput};
// Using custom separator instead of default "."
let json = r#"{"company": {"department": {"team": "engineering"}}}"#;
let result = JSONTools::new()
.flatten()
.separator("::") // Use "::" instead of "."
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"company::department::team": "engineering"}
assert!(flattened.contains("company::department::team"));
assert!(!flattened.contains("company.department.team"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§3. Key Transformations - Lowercase Keys
use json_tools_rs::{JSONTools, JsonOutput};
// Convert all keys to lowercase during processing
let json = r#"{"UserName": "John", "UserProfile": {"FirstName": "John"}}"#;
let result = JSONTools::new()
.flatten()
.lowercase_keys(true)
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"username": "John", "userprofile.firstname": "John"}
assert!(flattened.contains("username"));
assert!(flattened.contains("userprofile.firstname"));
assert!(!flattened.contains("UserName"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§4. Key Replacement Patterns - Literal Replacement
use json_tools_rs::{JSONTools, JsonOutput};
// Replace literal strings in keys
let json = r#"{"user_profile_name": "John", "user_profile_age": 30}"#;
let result = JSONTools::new()
.flatten()
.key_replacement("user_profile_", "person_") // Replace literal string
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"person_name": "John", "person_age": 30}
assert!(flattened.contains("person_name"));
assert!(flattened.contains("person_age"));
assert!(!flattened.contains("user_profile_"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§5. Key Replacement Patterns - Regex Replacement
use json_tools_rs::{JSONTools, JsonOutput};
// Replace using regex patterns in keys
let json = r#"{"user_name": "John", "admin_name": "Jane", "guest_name": "Bob"}"#;
let result = JSONTools::new()
.flatten()
.key_replacement("r'(user|admin)_'", "person_") // Regex pattern
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"person_name": "John", "person_name": "Jane", "guest_name": "Bob"}
// Note: This would cause collision without collision handling
assert!(flattened.contains("person_name"));
assert!(flattened.contains("guest_name"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§6. Value Replacement Patterns - Literal Replacement
use json_tools_rs::{JSONTools, JsonOutput};
// Replace literal strings in values
let json = r#"{"email": "user@example.com", "backup_email": "admin@example.com"}"#;
let result = JSONTools::new()
.flatten()
.value_replacement("@example.com", "@company.org") // Replace domain
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"email": "user@company.org", "backup_email": "admin@company.org"}
assert!(flattened.contains("@company.org"));
assert!(!flattened.contains("@example.com"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§7. Value Replacement Patterns - Regex Replacement
use json_tools_rs::{JSONTools, JsonOutput};
// Replace using regex patterns in values
let json = r#"{"role": "super", "level": "admin", "type": "user"}"#;
let result = JSONTools::new()
.flatten()
.value_replacement("r'^(super|admin)$'", "administrator") // Regex pattern
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"role": "administrator", "level": "administrator", "type": "user"}
assert!(flattened.contains(r#""role":"administrator""#));
assert!(flattened.contains(r#""level":"administrator""#));
assert!(flattened.contains(r#""type":"user""#));
}
JsonOutput::Multiple(_) => unreachable!(),
}§8. Filtering Options - Remove Empty Strings
use json_tools_rs::{JSONTools, JsonOutput};
// Remove keys that have empty string values
let json = r#"{"name": "John", "nickname": "", "age": 30}"#;
let result = JSONTools::new()
.flatten()
.remove_empty_strings(true)
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"name": "John", "age": 30} - "nickname" removed
assert!(flattened.contains("name"));
assert!(flattened.contains("age"));
assert!(!flattened.contains("nickname"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§9. Filtering Options - Remove Null Values
use json_tools_rs::{JSONTools, JsonOutput};
// Remove keys that have null values
let json = r#"{"name": "John", "age": null, "city": "NYC"}"#;
let result = JSONTools::new()
.flatten()
.remove_nulls(true)
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"name": "John", "city": "NYC"} - "age" removed
assert!(flattened.contains("name"));
assert!(flattened.contains("city"));
assert!(!flattened.contains("age"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§10. Filtering Options - Remove Empty Objects and Arrays
use json_tools_rs::{JSONTools, JsonOutput};
// Remove keys that have empty objects or arrays
let json = r#"{"user": {"name": "John"}, "tags": [], "metadata": {}}"#;
let result = JSONTools::new()
.flatten()
.remove_empty_objects(true)
.remove_empty_arrays(true)
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"user.name": "John"} - "tags" and "metadata" removed
assert!(flattened.contains("user.name"));
assert!(!flattened.contains("tags"));
assert!(!flattened.contains("metadata"));
}
JsonOutput::Multiple(_) => unreachable!(),
}§11. Collision Handling - Collect Values into Arrays
use json_tools_rs::{JSONTools, JsonOutput};
// When key replacements cause collisions, collect all values into an array
let json = r#"{"user_name": "John", "admin_name": "Jane"}"#;
let result = JSONTools::new()
.flatten()
.key_replacement("r'(user|admin)_'", "") // This creates collision: both become "name"
.handle_key_collision(true) // Collect values into array
.execute(json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Result: {"name": ["John", "Jane"]}
assert!(flattened.contains(r#""name":["John","Jane"]"#) ||
flattened.contains(r#""name": ["John", "Jane"]"#));
}
JsonOutput::Multiple(_) => unreachable!(),
}§12. Comprehensive Integration Example
use json_tools_rs::{JSONTools, JsonOutput};
// Comprehensive example combining multiple features for real-world usage
let complex_json = r#"{
"User_Profile": {
"Personal_Info": {
"FirstName": "John",
"LastName": "",
"Email": "john@example.com",
"Age": null
},
"Settings": {
"Theme": "dark",
"Notifications": {},
"Tags": []
}
},
"Admin_Profile": {
"Personal_Info": {
"FirstName": "Jane",
"Email": "jane@example.com",
"Role": "super"
}
}
}"#;
let result = JSONTools::new()
.flatten()
.separator("::") // Use custom separator
.lowercase_keys(true) // Convert all keys to lowercase
.key_replacement("r'(user|admin)_profile::'", "person::") // Normalize profile keys
.key_replacement("personal_info::", "info::") // Simplify nested keys
.value_replacement("@example.com", "@company.org") // Update email domain
.value_replacement("r'^super$'", "administrator") // Normalize role values
.remove_empty_strings(true) // Remove empty string values
.remove_nulls(true) // Remove null values
.remove_empty_objects(true) // Remove empty objects
.remove_empty_arrays(true) // Remove empty arrays
.handle_key_collision(true) // Handle any key collisions by collecting into arrays
.execute(complex_json).unwrap();
match result {
JsonOutput::Single(flattened) => {
// Verify the comprehensive transformation worked
// Note: Keys are transformed through multiple steps: lowercase + replacements
assert!(flattened.contains("@company.org"));
assert!(flattened.contains("administrator"));
assert!(!flattened.contains("lastname")); // Empty string removed
assert!(!flattened.contains("age")); // Null removed
assert!(!flattened.contains("notifications")); // Empty object removed
assert!(!flattened.contains("tags")); // Empty array removed
// The exact key structure depends on the order of transformations
println!("Comprehensive transformation result: {}", flattened);
}
JsonOutput::Multiple(_) => unreachable!(),
}
// Demonstrate unflattening with the same configuration
let flat_json = r#"{"person::info::name": "Alice", "person::settings::theme": "light"}"#;
let result = JSONTools::new()
.unflatten()
.separator("::")
.execute(flat_json).unwrap();
match result {
JsonOutput::Single(unflattened) => {
// Result: {"person": {"info": {"name": "Alice"}, "settings": {"theme": "light"}}}
assert!(unflattened.contains(r#""person""#));
assert!(unflattened.contains(r#""info""#));
assert!(unflattened.contains(r#""settings""#));
println!("Unflattening result: {}", unflattened);
}
JsonOutput::Multiple(_) => unreachable!(),
}Structs§
- Collision
Config - Configuration for collision handling strategies
- Filtering
Config - Configuration for filtering operations
- JSON
Tools - Unified JSON Tools API with builder pattern for both flattening and unflattening operations
- Processing
Config - Comprehensive configuration for JSON processing operations
- Replacement
Config - Configuration for replacement operations
Enums§
- Json
Input - Input type for JSON flattening operations with Cow optimization
- Json
Output - Output type for JSON flattening operations
- Json
Tools Error - Comprehensive error type for all JSON Tools operations with detailed information and suggestions