2 unstable releases
new 0.2.0 | Feb 13, 2025 |
---|---|
0.1.0 | Feb 9, 2025 |
#313 in Data structures
229 downloads per month
52KB
859 lines
json_deref
json_deref
is a Rust library for resolving internal dependencies in JSON structures. It automatically replaces placeholders (e.g., {some_dependency}
) in JSON strings with their corresponding values, simplifying the handling of self-referencing or cross-referencing JSON data. The library provides multiple utility functions for resolving JSON either into a Value
(from serde_json
) or into user-defined types.
Key Features
- Dependency resolution for self-referentional JSON Automatically resolves JSON placeholders (like
{neighbour_value}
,{../parent_value}
, e.t.c) to their corresponding values. - Dependency resolution for template JSON Automatically resolves JSON placeholders in template (like
{/object/field}
) to their corresponding values using data source JSON. - Absolute Path Expansion: Converts relative dependency paths into absolute paths.
- Resolving Embedded Dependencies Resolves multiple embedded dependencies in text
- Graceful Fallbacks If a dependency cannot be resolved, the placeholder will be replaced by its absolute path.
- No Recursion Only top-level dependencies are resolved. Nested dependencies in resolved text are not recursively processed. This prevents infinite resolution.
- Error-Tolerant The library does not generate errors during resolution. All dependencies are processed in a fail-safe manner. If a dependency cannot be resolved, the library will replace it with its absolute path (e.g., /some/absolute/path) rather than throwing an error.
Installation
Add json_deref
to your Cargo.toml
dependencies:
[dependencies]
json_deref = "0.2.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Examples of functionality
- Resolving internal dependencies
let input = json!({
"string_field": "Static Value",
"number_field": 123,
"boolean_field": true,
"null_field": null,
"absolute_field": "{/string_field}", // Absolute path
"relative_field": "{string_field}", // Sibling reference
"embedded_field": "Embedded: {string_field}", // Embedded dependency
"object_field": {
"parent_field": "{../relative_field}", // Resolves a field from parent object. Note that the dependencies will not be resolved recursively.
"out_of_bounds_field": "{../../boolean_field}" // Also resolves a field from parent object
},
"array_field": [
"Static Value", // Static value
"{../number_field}" // Sibling reference in array
],
"unresolvable_field": "{/nonexistent}" // Unresolvable absolute path
});
let resolved = input.resolve_internal_dependencies();
assert_eq!(resolved, json!({
"string_field": "Static Value", // Original value preserved
"number_field": 123, // Original value preserved
"boolean_field": true, // Original boolean preserved
"null_field": null, // Null value preserved
"absolute_field": "Static Value", // Resolved using absolute path
"relative_field": "Static Value", // Resolved sibling reference
"embedded_field": "Embedded: Static Value", // Embedded dependency resolved
"object_field": {
"parent_field": "{/string_field}", // Resolves a field from parent object. Note that the dependencies will not be resolved recursively.
"out_of_bounds_field": true // Also resolves a field from parent object
},
"array_field": [
"Static Value", // Static value unchanged
123 // Resolved sibling reference
],
"unresolvable_field": "{/nonexistent}" // Unresolved dependency remains unchanged
}));
- Resolving dependencies using both template and data source JSON
let template = json!({
"string_field": "{/data/string}",
"number_field": "{/data/number}",
"boolean_field": "{/data/boolean}",
"array_field": "{/data/array}",
"object_field": "{/data/object}",
"null_field": "{/data/null}",
"embedded_field": "Referenced: {/data/string}", // Embedded dependency
"unresolvable_field": "{/data/nonexistent}" // Unresolvable path
});
let source = json!({
"data": {
"string": "String Value",
"number": 123,
"boolean": false,
"array": ["a", "b", "c"],
"object": {"key": "value"},
"null": null
}
});
let resolved = template.resolve_template_with_source(&source);
assert_eq!(resolved, json!({
"string_field": "String Value",
"number_field": 123,
"boolean_field": false,
"array_field": ["a", "b", "c"],
"object_field": {"key": "value"},
"null_field": null,
"embedded_field": "Referenced: String Value",
"unresolvable_field": "{/data/nonexistent}" // Paths not found in source remain unchanged
}));
See additional examples in '/examples' dir
How It Works
json_deref uses the following steps to resolve a JSON structure:
Path Mapping
A map of dependencies is created by scanning the JSON strings for placeholders like {key} or {path/to/key}.
Path Conversion
Relative paths are converted to absolute paths for easier reference resolution.
Dependency Extraction
For each absolute path, the corresponding value in the JSON is extracted.
Resolution
Placeholders in the JSON are replaced with their resolved values.
Contributing
If you'd like to improve this library or suggest new features, feel free to fork the repository and submit a pull request.
Clone the repository: git clone https://github.com/Arsynth/json_deref.git Create a feature branch: git checkout -b feature/my-new-feature Submit your changes. License json_deref is licensed under the Apache-2.0 License.
Feel free to use, modify, and distribute the library in accordance with the terms of the license.
Dependencies
~0.7–1.5MB
~33K SLoC