added a readme
This commit is contained in:
+8
-2
@@ -3,8 +3,14 @@ name = "json_dotpath"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
|
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
license = "MIT"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
description = "Dotted path access to nested JSON objects (serde_json::Value)"
|
||||||
|
repository = "https://git.ondrovo.com/packages/json_dotpath"
|
||||||
|
readme = "README.md"
|
||||||
|
keywords = ["serde", "json", "dot"]
|
||||||
|
categories = [
|
||||||
|
"data-structures"
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "1"
|
serde = "1"
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# json_dotpath
|
||||||
|
|
||||||
|
Access members of nested JSON arrays and objects using "dotted paths".
|
||||||
|
|
||||||
|
The `DotPaths` trait is implemented for `serde_json::Value`,
|
||||||
|
`serde_json::Map<String, serde_json::Value>`, and `Vec<serde_json::Value>`.
|
||||||
|
|
||||||
|
Any serializable type or `serde_json::Value` can be stored to or retrieved from
|
||||||
|
the nested object. Any value stored in the object can also be modified in place
|
||||||
|
by getting a mutable reference.
|
||||||
|
|
||||||
|
This crate is useful for tasks such as working with dynamic JSON API payloads,
|
||||||
|
parsing config files, or polymorphic data store.
|
||||||
|
|
||||||
|
## Supported Operations
|
||||||
|
|
||||||
|
### Object and Array
|
||||||
|
- Set (dropping the original value, if any)
|
||||||
|
- Remove (remove and drop a value)
|
||||||
|
- Take (remove a value and deserialize it)
|
||||||
|
- Replace (take and set)
|
||||||
|
- Get (find & deserialize)
|
||||||
|
- Get a mutable reference to a Value
|
||||||
|
|
||||||
|
### Array
|
||||||
|
Array is an ordered sequence backed by a Vec. It has these additional operations:
|
||||||
|
|
||||||
|
- Prepend
|
||||||
|
- Append
|
||||||
|
- Insert, shifting the following elements
|
||||||
|
- Get the last element
|
||||||
|
|
||||||
|
### Null
|
||||||
|
JSON null can become an array or object by setting it's members (even nested), as if it was an array or object.
|
||||||
|
It becomes an array or object of the appropriate type based on the root key.
|
||||||
|
|
||||||
|
## Dotted Path Syntax
|
||||||
|
|
||||||
|
Array keys must be numeric (integer), or one of the special patterns listed below.
|
||||||
|
|
||||||
|
To avoid ambiguity, it's not allowed to use numeric keys (or keys starting with a number)
|
||||||
|
as map keys. Map keys must start with an ASCII letter or underscore and must not contain a dot (`.`).
|
||||||
|
|
||||||
|
### Array Index Patterns
|
||||||
|
|
||||||
|
- `-` ... prepend
|
||||||
|
- `<` ... prepend (or get first)
|
||||||
|
- `+` ... append
|
||||||
|
- `>` ... append (or get last)
|
||||||
|
- `<n`, e.g. `<5` ... insert before the n-th element
|
||||||
|
- `>n`, e.g. `>5` ... insert after the n-th element
|
||||||
|
|
||||||
|
### Path Examples
|
||||||
|
|
||||||
|
- Empty path ... access the root element
|
||||||
|
- `5` ... get the element `"five"` from `[0,1,2,3,4,"five"]`
|
||||||
|
- `a.b.c` ... get `1` from `{ "a": { "b": { "c": 1 } } }`
|
||||||
|
- `a.0.x` ... get `1` from `{ "a": [ { "x": 1 } ] }`
|
||||||
|
|
||||||
|
It's possible to create nested arrays or objects by setting a non-existent path,
|
||||||
|
provided the key syntax rules are maintained.
|
||||||
|
|
||||||
|
See unit tests for more examples.
|
||||||
+48
@@ -4,6 +4,8 @@ use serde_json::{Map, Value};
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
#[macro_use] extern crate serde_derive;
|
||||||
|
|
||||||
/// Access and mutate nested JSON elements by dotted paths
|
/// Access and mutate nested JSON elements by dotted paths
|
||||||
///
|
///
|
||||||
/// The path is composed of keys separated by dots, e.g. `foo.bar.1`.
|
/// The path is composed of keys separated by dots, e.g. `foo.bar.1`.
|
||||||
@@ -540,6 +542,7 @@ mod tests {
|
|||||||
use crate::DotPaths;
|
use crate::DotPaths;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
use serde::{Serialize,Deserialize};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_scalar_with_empty_path() {
|
fn get_scalar_with_empty_path() {
|
||||||
@@ -804,4 +807,49 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(json!({"one": "two", "x": {"bbb": ["betelgeuze"]}}), vec);
|
assert_eq!(json!({"one": "two", "x": {"bbb": ["betelgeuze"]}}), vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn stamps() {
|
||||||
|
let mut stamps = Value::Null;
|
||||||
|
// null will become Value::Array(vec![])
|
||||||
|
|
||||||
|
#[derive(Serialize,Deserialize,PartialEq,Default)]
|
||||||
|
struct Stamp {
|
||||||
|
country: String,
|
||||||
|
year: u32,
|
||||||
|
color: String,
|
||||||
|
#[serde(rename = "face value")]
|
||||||
|
face_value: String,
|
||||||
|
};
|
||||||
|
|
||||||
|
stamps.dot_set("0", json!({
|
||||||
|
"country": "British Mauritius",
|
||||||
|
"year": 1847,
|
||||||
|
"color": "orange",
|
||||||
|
"face value": "1 penny"
|
||||||
|
}));
|
||||||
|
|
||||||
|
// append
|
||||||
|
stamps.dot_set(">", Stamp {
|
||||||
|
country: "British Mauritius".to_string(),
|
||||||
|
year: 1847,
|
||||||
|
color: "blue".to_string(),
|
||||||
|
face_value: "2 pence".to_string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!("orange", stamps.dot_get::<String>("0.color").unwrap());
|
||||||
|
assert_eq!("blue", stamps.dot_get::<String>("1.color").unwrap());
|
||||||
|
|
||||||
|
assert_eq!(1847, stamps.dot_get::<Stamp>("1").unwrap().year);
|
||||||
|
|
||||||
|
// Remove the first stamp's "face value" attribute
|
||||||
|
assert_eq!(Some("1 penny".to_string()), stamps.dot_get("0.face value"));
|
||||||
|
stamps.dot_remove("0.face value");
|
||||||
|
assert_eq!(Option::<Value>::None, stamps.dot_get("0.face value"));
|
||||||
|
|
||||||
|
// change the second stamp's year
|
||||||
|
let old_year : u32 = stamps.dot_replace("1.year", 1850).unwrap();
|
||||||
|
assert_eq!(1847, old_year);
|
||||||
|
assert_eq!(1850, stamps.dot_get::<u32>("1.year").unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user