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.
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.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
}
We will embed the previous schema into the Rust program as a type definition using the
#[tldr]
procedural macro attribute provided by the treeldr-rust-macros
crate. This crate relies on the treeldr-rust-prelude
crate. We will also embed a JSON-LD context definition for the schema so we can later generate JSON-LD documents using the json-ld
crate.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" }
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
}
}
}
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
.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.
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();
The
#[treeldr]
macro provides convenient constructors for the types it generates. To create a new BlogPost
, simply call the new
constructor with the required parameters:let post = schema::example::BlogPost::new(
title,
content
);
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.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());
Last modified 9mo ago