json-ld Rust Implementation

repository·main·Indexed 41 days ago

https://github.com/timothee-haudebourg/json-ld

A high-performance Rust implementation of the W3C JSON-LD data interchange format. It supports core transformations including expansion, compaction, and flattening via the JsonLdProcessor trait. The library includes crates for serialization of RDF datasets, syntax utilities for parsing and printing, and a CLI tool for fetching and processing JSON-LD documents.

Tokens
35.8K
Snippets
105
Records
139
Agent score
98%

What's inside json-ld

  1. Use the JSON-LD syntax library

    main

    The json-ld-syntax crate provides low-level utilities for handling JSON-LD structures. Specifically, it includes functions to:

    1. Parse JSON-LD contexts: Convert context definitions into usable internal representations.
    2. Print JSON-LD documents: Serialize or format JSON-LD documents for output.
  2. How to use the JsonLdProcessor trait

    main
    The JsonLdProcessor trait is the primary entry point for the library. It provides access to all core JSON-LD transformation algorithms, including context processing, expansion, compaction, and flattening. To use it, you typically call these methods on a document representation like RemoteDocument or RemoteDocumentReference while providing a loader (e.g., NoLoader or FsLoader) to handle fetching remote resources.
  3. Optimize performance with Fast IRIs and Blank Node Identifiers

    main

    To avoid unnecessary allocations and expensive comparisons, it is highly recommended to use lightweight datatypes for IRIs and Blank Node Identifiers instead of raw strings.

    Using rdf_types::vocabulary::Index allows you to represent each distinct identifier with a unique index. When using this pattern, you must pass an rdf_types::IndexVocabulary (which maps indices back to their original representation) to the transformation functions. This pattern is supported via methods like expand_with.

  4. Run the official W3C JSON-LD test suite

    main

    To run the full test suite, which includes the official W3C JSON-LD API test suite, you must first initialize and update the submodules to clone the test data. Then, run cargo test to execute the tests generated by the json-ld-testing crate.

    git submodule init
    git submodule update
    cargo test
  5. Compact a JSON-LD document

    main

    Compaction reduces the size of a JSON-LD document by applying a specific context. There are two ways to perform compaction depending on your starting point:

    1. From a remote document: Use JsonLdProcessor::compact (or compact_with) on a RemoteDocument or RemoteDocumentReference.
    2. From an expanded document: Use the Compact::compact method on an ExpandedDocument.

    Compaction requires a RemoteContextReference to define the context being applied.

    use static_iref::iri;
    use json_ld::{JsonLdProcessor, Options, RemoteDocumentReference, RemoteContextReference, syntax::Print};
    
    let input = RemoteDocumentReference::iri(iri!("https://example.com/sample.jsonld").to_owned());
    let context = RemoteContextReference::iri(iri!("https://example.com/context.jsonld").to_owned());
    
    let mut loader = json_ld::FsLoader::default();
    loader.mount(iri!("https://example.com/").to_owned(), "examples");
    
    let compact = input
      .compact(context, &mut loader)
      .await
      .expect("compaction failed");
    
    println!("output: {}", compact.pretty_print());
  6. Flatten a JSON-LD document

    main

    Flattening moves nested nodes out, resulting in a list of all nodes declared in the document.

    • From a remote document: Use JsonLdProcessor::flatten (or flatten_with). This returns a JSON-LD document.
    • From an expanded document: Use the Flatten::flatten (or flatten_with) method. This returns a FlattenedDocument (a list of nodes).

    Flattening requires an rdf_types::MetaGenerator to assign identifiers to nested anonymous nodes. The most common implementation is rdf_types::generator::Blank.

    use static_iref::iri;
    use json_ld::{JsonLdProcessor, Options, RemoteDocumentReference, syntax::Print};
    
    let input = RemoteDocumentReference::iri(iri!("https://example.com/sample.jsonld").to_owned());
    let mut loader = json_ld::FsLoader::default();
    loader.mount(iri!("https://example.com/").to_owned(), "examples");
    
    let mut generator = rdf_types::generator::Blank::new();
    
    let nodes = input
      .flatten(&mut generator, &mut loader)
      .await
      .expect("flattening failed");
    
    println!("output: {}", nodes.pretty_print());
  7. Perform JSON-LD compaction using the Compact trait

    main

    To perform the JSON-LD compaction algorithm, use the Compact trait provided by the json-ld-compaction crate. This trait is designed to work with the core json-ld crate to reduce the size of a JSON-LD document by mapping terms to a provided context.

    // Note: The specific method signatures are defined in the Compact trait within the json-ld-compaction crate.
  8. Expand a JSON-LD document

    main

    Expansion transforms a JSON-LD document into an expanded form. You can describe the document to be expanded using:

    • RemoteDocument: Wraps the JSON representation alongside its remote URL.
    • RemoteDocumentReference: Represents only a URL, allowing a loader to fetch the document via dereferencing.

    Use the JsonLdProcessor::expand method on the document. If you are using lightweight index types for IRIs, use expand_with instead.

    use iref::IriBuf;
    use static_iref::iri;
    use json_ld::{JsonLdProcessor, Options, RemoteDocument, syntax::{Value, Parse}};
    
    // Create a "remote" document by parsing a file manually.
    let input = RemoteDocument::new(
      Some(iri!("https://example.com/sample.jsonld").to_owned()),
      Some("application/ld+json".parse().unwrap()),
      Value::parse_str(r"#{
          "@context": {
            "name": "http://xmlns.com/foaf/0.1/name"
          },
          "@id": "https://www.rust-lang.org",
          "name": "Rust Programming Language"
        }"#).expect("unable to parse file").0
    );
    
    let mut loader = json_ld::NoLoader;
    
    let expanded = input
      .expand(&mut loader)
      .await
      .expect("expansion failed");
  9. Display vocabulary-dependent values using WithContext

    main

    When using vocabularies (like IndexVocabulary), IRIs and Blank IDs are stored as indices rather than text, making them difficult to print directly. To display them, use the contextual::WithContext trait, which provides the .with() method. This allows you to render the value using the provided vocabulary as context.

    use static_iref::iri;
    use rdf_types::vocabulary::{IriVocabularyMut, IndexVocabulary};
    use contextual::WithContext;
    
    let mut vocabulary: IndexVocabulary = IndexVocabulary::new();
    let i = vocabulary.insert(iri!("https://docs.rs/contextual"));
    let value = rdf_types::Subject::Iri(i);
    
    println!("{}", value.with(&vocabulary));
  10. Use core JSON-LD types and abstractions

    main

    The json-ld-core crate provides the fundamental building blocks for JSON-LD manipulation. Key exported abstractions include:

    • Data Models: Node, Object, Value, and IndexedNode for representing JSON-LD structures.
    • Context & Vocabulary: Context for managing JSON-LD contexts.
    • Processing: Flatten for flattening operations and LdQuads/RdfQuads for RDF-based representations.
    • Containers: Container and ContainerKind for handling JSON-LD containers.
    • Identifiers: Id for managing JSON-LD identifiers.
    • Utilities: utils and warning for error/warning handling and general helpers.