Expand description
Provides a high level way of lazily dereferencing JSON Pointer in serde Value
.
It can operate in-memory or on files (JSON
or YAML
).
To deserialize an object of type T
or a pointer to
local or distant document referencing an object of type T
,
we use the type SparseSelector.
The root document is wrapped in a SparseRoot. This allow a coordination of the state and the cached values.
Let’s take the following JSON
document :
{
"hello": "world",
"obj": {
"key1": {
"$ref": "#/hello"
},
"key2": "universe"
}
}
Now, let’s parse it using the SparseSelector and the SparseRoot :
extern crate sppparse;
use serde::{Deserialize, Serialize};
use sppparse::{Sparsable, SparsePointer, SparseRoot, SparseSelector};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Serialize, Sparsable)]
struct ObjectExampleParsed {
hello: String,
obj: HashMap<String, SparseSelector<String>>,
}
fn main() {
let doc: SparseRoot<ObjectExampleParsed> = SparseRoot::new_from_file(PathBuf::from(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
"./examples/read_multi_files.json"
)))
.unwrap();
println!("Full object {:#?}", doc.root_get().unwrap());
println!(
"A single ref {:#?}",
doc.root_get().unwrap().obj.get("key1").unwrap().get()
);
println!(
"A single ref {:#?}",
doc.root_get().unwrap().obj.get("key2").unwrap().get()
);
}
§In-memory
Let’s take the following JSON
example document:
{
"hello": "world",
"obj": {
"key1":
{
"$ref": "#/hello"
}
}
}
We can just pass Value or objects that implements Serialize to the SparseRoot
extern crate sppparse;
use serde::{Deserialize, Serialize};
use serde_json::json;
use sppparse::{Sparsable, SparsePointer, SparseRoot, SparseSelector};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Serialize, Sparsable)]
struct ObjectExampleParsed {
hello: String,
obj: HashMap<String, SparseSelector<String>>,
}
fn main() {
let json_value = json!({
"hello": "world",
"obj": {
"key1": {
"$ref": "#/hello"
}
}
});
let parsed_obj: SparseRoot<ObjectExampleParsed> =
SparseRoot::new_from_value(json_value, PathBuf::from("hello.json"), vec![]).unwrap();
println!(
"{}",
parsed_obj
.root_get()
.unwrap()
.obj
.get("key1")
.unwrap()
.get()
.expect("the dereferenced pointer")
);
}
§File backed
If we take the same object as the in-memory example, but reading from a file, the rust code would like the following :
extern crate sppparse;
use serde::{Deserialize, Serialize};
use sppparse::{Sparsable, SparsePointer, SparseRoot, SparseSelector};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Serialize, Sparsable)]
struct ObjectExampleParsed {
hello: String,
obj: HashMap<String, SparseSelector<String>>,
}
fn main() {
let val: SparseRoot<ObjectExampleParsed> = SparseRoot::new_from_file(PathBuf::from(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
"./examples/read_single_file.json"
)))
.unwrap();
println!(
"{}",
val.root_get()
.unwrap()
.obj
.get("key1")
.unwrap()
.get()
.expect("the dereferenced pointer")
);
}
§Updates
Using Sparse, it’s also possible to modify the parsed value and then save them to disk.
See the following example :
extern crate sppparse;
use serde::{Deserialize, Serialize};
use sppparse::{Sparsable, SparsePointer, SparseRoot, SparseSelector};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Serialize, Sparsable)]
struct ObjectExampleParsed {
hello: String,
obj: HashMap<String, SparseSelector<String>>,
}
fn main() {
let mut val: SparseRoot<ObjectExampleParsed> = SparseRoot::new_from_file(PathBuf::from(concat!(
env!("CARGO_MANIFEST_DIR"),
"/",
"./examples/read_single_file.json"
)))
.unwrap();
println!(
"Before : {}",
val.root_get()
.unwrap()
.obj
.get("key1")
.unwrap()
.get()
.expect("the dereferenced pointer")
);
{
let state = val.state().clone();
let mut root_mut = val.root_get_mut().unwrap();
let key1 = root_mut.obj.get_mut("key1").unwrap();
let mut key1_deref = key1.get_mut(state).unwrap();
*key1_deref = "universe".to_string();
key1_deref.sparse_save().unwrap();
val.sparse_updt().unwrap();
}
println!(
"After : {}",
val.root_get()
.unwrap()
.obj
.get("key1")
.unwrap()
.get()
.expect("the dereferenced pointer")
);
// To persist those modification to disk use :
//
// val.save_to_disk(None).unwrap()
}
Structs§
- Sparse
Metadata - Metadata about the pointer
- Sparse
Ref - An owned dynamic ref
- Sparse
RefRaw - A raw dynamic ref
- Sparse
RefRaw Inline - An owned dynamic ref
- Sparse
Root - A structure to hold the root document as well as its state.
- Sparse
State - State in which the documents are cached
- Sparse
State File - A document in the state
- Sparse
Value - A value extracted from a SparsePointer
- Sparse
Value Mut - A value extracted from a SparsePointer (mutable)
Enums§
- Sparse
Error - An error throwable by Sparse
- Sparse
File Format - Format in which Sparse should read/write the files
- Sparse
Pointed Value - A raw selector between a raw object, a raw pointer or an owned pointer
- Sparse
Selector - An owned selector between a raw object, a raw pointer or an owned pointer
Constants§
- MAX_
SPARSE_ DEPTH - The max stack frames Sparse will go before returning a cyclic.
Traits§
- Sparsable
Trait - Implements base to be parsed by Sparse
- Sparse
Pointer - Base shared by owned pointers
- Sparse
Pointer Raw - Base shared by raw pointers