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