SpruceKit
SpruceID
  • 🌲SpruceKit Introduction
    • Decentralized Identity Overview
    • Glossary
  • ⚡Quickstart
  • SpruceKit Mobile
    • SpruceKit Showcase App
      • Installation
      • Getting Started
      • Issue a Showcase Credential
      • Present a Showcase Credential
    • SpruceKit Mobile SDK
      • Introduction
      • Core Components
        • StorageManager
        • KeyManager
        • CredentialPack
        • Card
        • IsoMdlPresentation
        • mDocReader/IsomDLReader
        • Document Scanner
      • SpruceKit iOS SDK
        • Installation
        • Build a Wallet
          • Accept a W3C VC
          • Present a W3C VC
          • Present mDL in-person/offline
          • Present an mDL over the internet
        • Build a Verifier
          • Verify a W3C VC
          • Verify an mDL in-person/offline
          • Verify an mDL over the internet
      • SpruceKit Android SDK
        • Installation
        • Build a Wallet
          • Accept a W3C VC
          • Present a W3C VC
          • Present an mDL in-person/offline
          • Present an mDL over the internet
        • Build a Verifier
          • Verify a W3C VC
          • Verify an mDL in-person/offline
          • Verify an mDL over the internet
  • Verifiable Digital Credentials
    • ⚙️DIDKit
      • Installation
      • Core Concepts
      • DID Methods
      • Runtime Configuration
      • Specifications and Dependencies
      • Quickstart
      • DIDKit Packages
        • Command Line Interface
        • HTTP Server
        • Rust Crate
        • C Interface
        • Java and Android
        • Python
        • Javascript
      • DIDKit Examples
        • Core Functions (CLI)
        • Core Functions (HTTP)
        • did-web in minutes
        • Batch Generation & Verification
    • 🪪ISO mDL
      • Quickstart
      • Core Concepts
      • User Guide
  • Schema Definition Language
    • 🔗TreeLDR
      • TreeLDR Quickstart
        • First Schema
        • Compilation into JSON Schema
        • Compilation into JSON-LD Context
        • Writing a Layout
        • Simple Rust Integration
      • Types
        • Literal Types
      • Layouts
        • Primitive Layouts
        • Literal Layouts
        • Enumeration
        • Array Layout
        • References
      • Compiling
        • Schema Definition Formats
          • JSON Schema
          • JSON-LD Context
          • Resource Description Framework (RDF)
        • Programming Languages
          • Compiling to Rust
      • RDF Vocabulary
      • 💡TreeLDR Basics
        • Types and Layouts
        • Properties
        • Syntax
  • Witness for Credential Claims
    • 🔭Rebase
      • Core Library
      • Rust Client/Witness SDK
      • WASM Client SDK
      • Simple "Basic Post" Schema
      • DNS Witness Flow Schema
  • References
    • Contributing
    • Code of Conduct
Powered by GitBook
On this page
  • Project Creation
  • TreeLDR Schema Definition
  • Rust Integration
  • Type Definitions
  • JSON-LD Context Definition
  • Main Function Definition

Was this helpful?

  1. Schema Definition Language
  2. TreeLDR
  3. TreeLDR Quickstart

Simple Rust Integration

This section shows how to use TreeLDR in a Rust application to define type definitions and boilerplate code. We will write a simple Rust program to create a new blog post from the command line and generate a JSON-LD document from it written on the standard output.

Project Creation

First, create a new Rust project using cargo in your command line:

cargo new mkpost
cd mkpost

The src directory will contain the sources of our application. For now, it only contains a main.rs file with a dummy main function definition.

TreeLDR Schema Definition

In the src directory, create a new schema.tldr file containing the following BlogPost type definition:

base <https://example.com/>;
use <http://www.w3.org/2001/XMLSchema#> as xs;

/// Blog post.
type BlogPost {
	/// Title.
	title: required xs:string,

	/// Post content.
	content: required xs:string
}

Rust Integration

First, add those two crates to the dependencies of the Rust program by adding the following lines to the Cargo.toml file under the [dependencies] section:

treeldr-rust-macros = { git = "https://github.com/spruceid/treeldr.git" }​
treeldr-rust-prelude = { git = "https://github.com/spruceid/treeldr.git" }​
json-ld = { git = "https://github.com/timothee-haudebourg/json-ld.git", branch = "c47ce83" }

Type Definitions

Add the following module definition annotated with the #[tldr] procedural macro attribute to the src/main.rs file:

#[tldr("src/schema.tldr")]
mod schema {
	#[prefix("http://www.w3.org/2001/XMLSchema#")]
	pub mod xs {}

	#[prefix("https://example.com/")]
	pub mod example {}
}

The arguments to the #[tldr] macro lists all the files we want to include in the Rust program in the schema module. The submodules annotated with the #[prefix] macro specify where to put the types. Here, every layout prefixed by http://www.w3.org/2001/XMLSchema# will be put inside the schema::xs module, while the layouts prefixed by https://example.com/ will be put inside the schema::example module.

At compile time, this macro call will expand to the following module:

mod schema {
	pub mod xs {
		pub type String = ::std::alloc::String;
	}

	pub mod example {
		pub struct BlogPost {
			title: super::xs::Text,
			content: super::xs::Text
		}
	}
}

JSON-LD Context Definition

The JsonLdContext derive attribute is not yet implemented. You can skip this step until it is released.

Inside the schema::example module declaration add the following lines:

#[derive(JsonLdContext)]
pub type BlogPost;

This will force TreeLDR to statically embed a JSON-LD context definition for the BlogPost layout by implementing json_ld::StaticContext for BlogPost.

Main Function Definition

Now that the type definitions and trait implementations are ready we can focus on the main function itself. The function will perform the following simple steps:

  • Read the title and content of the post from the standard input.

  • Build the post.

  • Convert it to JSON-LD.

  • Print it to the standard output.

Read the Post Data

Replace the main function body with the following:

let mut title = String::new();
let mut content = String::new();

std::io::stdin().read_line(&mut title).unwrap();
std::io::stdin().read_line(&mut content).unwrap();

Build the Post

The #[treeldr] macro provides convenient constructors for the types it generates. To create a new BlogPost, simply call the newconstructor with the required parameters:

let post = schema::example::BlogPost::new(
	title,
	content
);

Conversion to JSON-LD

The #[treeldr] macro automatically provides a conversion function to JSON-LD by implementing the treeldr_rust_prelude::IntoJsonLd trait for all the generated types:

use treeldr_rust_prelude::IntoJsonLd;
let mut json_ld: json_ld::syntax::Value<json_ld::syntax::StaticContextEntry, _> = post.into_json_ld();

We then add the BlogPost JSON-LD context provided by its json_ld::StaticContext implementation to the document:

use json_ld::StaticContext;
json_ld.as_object_mut().unwrap().append_context(
	schema::example::BlogPost::LD_CONTEXT
)

The json_ld::StaticContext trait is not yet released. You can skip this last step until it is.

Print the Output

We use the pretty_print method provided by the json_ld::syntax::Print trait to print the resulting JSON-LD document to the standard output:

println!("{}", json_ld.pretty_print());
PreviousWriting a LayoutNextTypes

Last updated 1 year ago

Was this helpful?

We will embed the previous schema into the Rust program as a type definition using the #[tldr] procedural macro attribute provided by the . This crate relies on the . We will also embed a JSON-LD context definition for the schema so we can later generate JSON-LD documents using the crate.

🔗
treeldr-rust-macros crate
treeldr-rust-prelude crate
json-ld