Crate sppparse[−][src]
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
SparseMetadata | Metadata about the pointer |
SparseRef | An owned dynamic ref |
SparseRefRaw | A raw dynamic ref |
SparseRefRawInline | An owned dynamic ref |
SparseRoot | A structure to hold the root document as well as its state. |
SparseState | State in which the documents are cached |
SparseStateFile | A document in the state |
SparseValue | A value extracted from a SparsePointer |
SparseValueMut | A value extracted from a SparsePointer (mutable) |
Enums
SparseError | An error throwable by Sparse |
SparseFileFormat | Format in which Sparse should read/write the files |
SparsePointedValue | A raw selector between a raw object, a raw pointer or an owned pointer |
SparseSelector | 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
SparsableTrait | Implements base to be parsed by Sparse |
SparsePointer | Base shared by owned pointers |
SparsePointerRaw | Base shared by raw pointers |
Derive Macros
Sparsable |