added a readme

master
Ondřej Hruška 4 years ago
parent 0e6fdc0c5c
commit 00270d811b
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 10
      Cargo.toml
  2. 63
      README.md
  3. 48
      src/lib.rs

@ -3,8 +3,14 @@ name = "json_dotpath"
version = "0.1.0"
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
license = "MIT"
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]
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.

@ -4,6 +4,8 @@ use serde_json::{Map, Value};
use std::cmp::Ordering;
use std::mem;
#[macro_use] extern crate serde_derive;
/// Access and mutate nested JSON elements by dotted paths
///
/// The path is composed of keys separated by dots, e.g. `foo.bar.1`.
@ -540,6 +542,7 @@ mod tests {
use crate::DotPaths;
use serde_json::json;
use serde_json::Value;
use serde::{Serialize,Deserialize};
#[test]
fn get_scalar_with_empty_path() {
@ -804,4 +807,49 @@ mod tests {
);
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());
}
}

Loading…
Cancel
Save