JSON Repair¶
Vexy JSON provides advanced JSON repair capabilities that can automatically fix common JSON formatting issues. The repair system uses confidence scoring and multiple strategies to intelligently fix malformed JSON.
Overview¶
The JSON repair system operates on three levels:
- Basic Repair: Simple bracket balancing and quote fixing
- Advanced Repair: Intelligent pattern recognition and multi-strategy fixes
- Enhanced Repair: Detailed tracking and confidence scoring
Basic Repair¶
Simple Usage¶
use vexy_json_core::repair::JsonRepairer;
let mut repairer = JsonRepairer::new(10); // Max 10 repairs
let malformed = r#"{"key": "value", "missing": "quote}"#;
match repairer.repair(malformed) {
Ok((fixed, repairs)) => {
println!("Fixed: {}", fixed);
println!("Applied {} repairs", repairs.len());
}
Err(e) => println!("Repair failed: {}", e),
}
Common Repairs¶
The basic repairer handles:
- Missing quotes:
{key: "value"}
→{"key": "value"}
- Bracket imbalances:
{"key": "value"
→{"key": "value"}
- Trailing commas:
{"key": "value",}
→{"key": "value"}
- Single quotes:
{'key': 'value'}
→{"key": "value"}
Advanced Repair¶
Configuration¶
use vexy_json_core::repair::advanced::{AdvancedJsonRepairer, TypeCoercionRules};
let mut repairer = AdvancedJsonRepairer::new()
.with_confidence_threshold(0.7)
.with_type_coercion_rules(TypeCoercionRules {
unquote_numbers: true,
fix_literals: true,
fix_quotes: true,
quote_keys: true,
});
let (fixed, strategies) = repairer.repair(input)?;
Repair Strategies¶
The advanced repairer includes multiple strategies:
Type Coercion¶
// Input: {"count": "42", "price": "19.99"}
// Output: {"count": 42, "price": 19.99}
// Input: {"flag": "true", "value": "null"}
// Output: {"flag": true, "value": null}
Quote Normalization¶
// Input: {'name': 'John', "age": '30'}
// Output: {"name": "John", "age": "30"}
Key Quoting¶
// Input: {name: "John", age: 30}
// Output: {"name": "John", "age": 30}
Comma Insertion¶
// Input: {"a": 1 "b": 2}
// Output: {"a": 1, "b": 2}
Confidence Scoring¶
Each repair strategy has a confidence score:
use vexy_json_core::repair::advanced::RepairConfidence;
let (fixed, strategies) = repairer.repair(input)?;
for strategy in strategies {
println!("Repair: {}", strategy.action.description);
println!("Confidence: {:.2}", strategy.confidence.value());
if strategy.confidence.is_high() {
println!("High confidence repair");
}
}
Preview Mode¶
Test repairs without applying them:
let mut repairer = AdvancedJsonRepairer::new()
.with_preview_mode(true);
let (original, strategies) = repairer.repair(input)?;
// original == input (unchanged)
// strategies contains what would be applied
Enhanced Repair with Tracking¶
Detailed Repair Tracking¶
use vexy_json_core::parser::parse_with_detailed_repair_tracking;
let result = parse_with_detailed_repair_tracking(input, options)?;
match result {
EnhancedParseResult::Success { value, tier, repairs } => {
println!("Parsed successfully using {:?}", tier);
if !repairs.is_empty() {
println!("Applied {} repairs:", repairs.len());
for repair in repairs {
println!(" {}", repair.description);
}
}
}
EnhancedParseResult::Failure { errors, tier, repairs } => {
println!("Parse failed at {:?} tier", tier);
for error in errors {
println!("Error: {}", error);
}
}
}
Three-Tier Parsing¶
The enhanced parser uses a three-tier strategy:
- Fast Tier: Standard
serde_json
for maximum performance - Forgiving Tier: Vexy JSON parser for non-standard JSON
- Repair Tier: Automatic repair for malformed JSON
use vexy_json_core::parser::parse_with_fallback;
let result = parse_with_fallback(input, options);
// Automatically tries all three tiers
Repair History and Analytics¶
Tracking Repair History¶
use vexy_json_core::repair::advanced::AdvancedJsonRepairer;
let mut repairer = AdvancedJsonRepairer::new();
// Perform multiple repairs
let _ = repairer.repair(input1)?;
let _ = repairer.repair(input2)?;
let _ = repairer.repair(input3)?;
// Analyze repair history
let history = repairer.history();
println!("Total repairs: {}", history.len());
for entry in history.entries() {
println!("Repair at {:?}: {} strategies applied",
entry.timestamp, entry.strategies.len());
}
Repair Statistics¶
// Get repair statistics
let stats = history.statistics();
println!("Most common repair: {:?}", stats.most_common_repair);
println!("Average confidence: {:.2}", stats.average_confidence);
println!("Success rate: {:.2}%", stats.success_rate * 100.0);
Custom Repair Strategies¶
Implementing Custom Repairs¶
use vexy_json_core::repair::advanced::{RepairStrategy, RepairAction, RepairType, RepairConfidence};
fn create_custom_repair(input: &str) -> Option<RepairStrategy> {
// Custom logic to detect and fix specific issues
if input.contains("specific_pattern") {
Some(RepairStrategy {
action: RepairAction {
action_type: RepairType::ReplaceText,
position: 0,
original: "specific_pattern".to_string(),
replacement: "fixed_pattern".to_string(),
description: "Fixed specific pattern".to_string(),
},
confidence: RepairConfidence::new(0.9),
alternatives: vec![],
})
} else {
None
}
}
Integration with Parsing¶
Automatic Repair During Parsing¶
use vexy_json_core::{parse_with_options, ParserOptions};
let options = ParserOptions {
enable_repair: true,
max_repairs: 50,
fast_repair: false,
report_repairs: true,
..Default::default()
};
match parse_with_options(input, options) {
Ok(value) => println!("Parsed successfully: {:?}", value),
Err(e) => println!("Parse failed: {}", e),
}
Repair-First Parsing¶
use vexy_json_core::parser::parse_with_fallback;
// Always try repair if normal parsing fails
let result = parse_with_fallback(input, options);
Performance Considerations¶
Fast vs. Thorough Repair¶
// Fast repair (less thorough but faster)
let options = ParserOptions {
fast_repair: true,
..Default::default()
};
// Thorough repair (more comprehensive but slower)
let options = ParserOptions {
fast_repair: false,
max_repairs: 100,
..Default::default()
};
Memory Usage¶
// Limit memory usage with cached vs. non-cached repairers
let fast_repairer = JsonRepairer::new_without_cache(10);
let cached_repairer = JsonRepairer::new(10); // Uses internal cache
Error Handling¶
Repair Failures¶
use vexy_json_core::repair::JsonRepairer;
let mut repairer = JsonRepairer::new(5);
match repairer.repair(input) {
Ok((fixed, repairs)) => {
println!("Successfully applied {} repairs", repairs.len());
}
Err(repair_error) => {
match repair_error {
RepairError::TooManyRepairs => {
println!("Too many repairs needed");
}
RepairError::UnrepairableInput => {
println!("Input cannot be repaired");
}
RepairError::InvalidInput(msg) => {
println!("Invalid input: {}", msg);
}
}
}
}
Graceful Degradation¶
fn parse_with_graceful_degradation(input: &str) -> Result<Value, String> {
// Try standard parsing first
if let Ok(value) = parse(input) {
return Ok(value);
}
// Try repair
let mut repairer = JsonRepairer::new(10);
if let Ok((fixed, _)) = repairer.repair(input) {
if let Ok(value) = parse(&fixed) {
return Ok(value);
}
}
// Fall back to partial parsing or error
Err("Could not parse or repair JSON".to_string())
}
Best Practices¶
When to Use Repair¶
- User Input: When parsing user-provided JSON
- Legacy Data: When working with old or non-standard JSON
- Data Migration: When converting between JSON formats
- API Integration: When consuming APIs with inconsistent JSON
Configuration Guidelines¶
// For user input (be forgiving)
let user_input_repairer = AdvancedJsonRepairer::new()
.with_confidence_threshold(0.5) // Lower threshold
.with_type_coercion_rules(TypeCoercionRules {
unquote_numbers: true,
fix_literals: true,
fix_quotes: true,
quote_keys: true,
});
// For critical data (be strict)
let critical_repairer = AdvancedJsonRepairer::new()
.with_confidence_threshold(0.9) // Higher threshold
.with_preview_mode(true); // Review before applying
Testing Repair Logic¶
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_repair_confidence() {
let mut repairer = AdvancedJsonRepairer::new();
let (fixed, strategies) = repairer.repair(r#"{"key": "value",}"#).unwrap();
assert_eq!(fixed, r#"{"key": "value"}"#);
assert!(!strategies.is_empty());
assert!(strategies[0].confidence.is_high());
}
}
The JSON repair system provides powerful tools for handling malformed JSON while maintaining safety and providing visibility into what changes were made.