Skip to content

Commit

Permalink
Rust generator v0.2 (#162)
Browse files Browse the repository at this point in the history
* Add `SerializeLd` and `DeserializeLd` derive macros.
* Add preset layouts.
* Add `tldr` and `tldr_include` macros.
  • Loading branch information
timothee-haudebourg authored Dec 8, 2023
1 parent 5182482 commit 3d4e745
Show file tree
Hide file tree
Showing 44 changed files with 4,696 additions and 90 deletions.
23 changes: 18 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[workspace]
members = [
"layouts",
# "layouts/distiller"
"generators/rust/treeldr-rs",
"generators/rust/treeldr-rs-macros",
"generators/rust/generator"
]
resolver = "2"

Expand All @@ -11,21 +13,32 @@ edition = "2021"
authors = ["Spruce Systems Inc."]

[workspace.dependencies]
treeldr-layouts = { path = "layouts/core", version = "0.2.0" }
# treeldr-build = { path = "layouts/build", version = "0.2.0" }
treeldr-layouts = { path = "layouts", version = "0.2.0" }
treeldr-macros = { path = "generators/rust/treeldr-rs-macros", version = "0.2.0" }
treeldr-gen-rust = { path = "generators/rust/generator", version = "0.2.0" }

log = "0.4"
educe = "0.4.23"
num-traits = "0.2"
num-bigint = "0.4"
num-rational = "0.4"
iref = "3.1.3"
static-iref = "3.0"
rdf-types = "0.18.1"
rdf-types = "0.18.2"
xsd-types = { git = "https://github.com/timothee-haudebourg/xsd-types.git" }
grdf = { version = "0.22.1", features = ["serde"] }
btree-range-map = { version = "0.7.2", features = ["serde"] }
langtag = "0.3.4"
thiserror = "1.0.50"
serde = "1.0.192"
serde_json = { version = "1.0", features = ["arbitrary_precision"] }

locspan = "0.8.2"
nquads-syntax = "0.17.0"
nquads-syntax = "0.17.0"

clap = "4.0"
stderrlog = "0.5"

syn = "2.0.29"
proc-macro2 = "1.0.66"
quote = "1.0.33"
21 changes: 21 additions & 0 deletions generators/rust/generator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "treeldr-gen-rust"
description = "TreeLDR Layouts to Rust"
version.workspace = true
authors.workspace = true
edition.workspace = true

[dependencies]
treeldr-layouts.workspace = true
rdf-types.workspace = true
iref.workspace = true
grdf.workspace = true
syn.workspace = true
proc-macro2.workspace = true
quote.workspace = true
log.workspace = true
thiserror.workspace = true

clap = { workspace = true, features = ["derive"] }
stderrlog.workspace = true
serde_json.workspace = true
105 changes: 105 additions & 0 deletions generators/rust/generator/src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use iref::IriBuf;
use rdf_types::Term;
use std::{fs, path::PathBuf, process::ExitCode};
use treeldr_layouts::{abs, distill::RdfContext, layout::LayoutType, Ref};

#[derive(clap::Parser)]
#[clap(name="treeldr", author, version, about, long_about = None)]
struct Args {
/// Input files.
filenames: Vec<PathBuf>,

/// Layout to generate.
#[clap(long, short)]
layout: Option<IriBuf>,

/// Sets the level of verbosity.
#[clap(short, long = "verbose", action = clap::ArgAction::Count)]
verbosity: u8,
}

enum DefaultLayoutRef {
Unknown,
Some(Ref<LayoutType>),
None,
}

impl DefaultLayoutRef {
pub fn set(&mut self, layout_ref: Ref<LayoutType>) {
match self {
Self::Unknown => *self = Self::Some(layout_ref),
Self::Some(_) => *self = Self::None,
Self::None => (),
}
}
}

fn main() -> ExitCode {
// Parse options.
let args: Args = clap::Parser::parse();

// Initialize logger.
stderrlog::new()
.verbosity(args.verbosity as usize)
.init()
.unwrap();

// Initialize the layout builder.
let mut builder = abs::Builder::new();

let mut default_layout_ref = DefaultLayoutRef::Unknown;

for filename in args.filenames {
let content = fs::read_to_string(filename).unwrap();

match serde_json::from_str::<abs::syntax::Layout>(&content) {
Ok(abstract_layout) => match abstract_layout.build(&mut builder) {
Ok(layout_ref) => default_layout_ref.set(layout_ref),
Err(e) => {
log::error!("compile error: {e}");
return ExitCode::FAILURE;
}
},
Err(e) => {
log::error!("parse error: {e}")
}
}
}

let layouts = builder.build();

let layout_ref = match args.layout {
Some(iri) => {
let term = Term::iri(iri);
if layouts.layout(&term).is_some() {
Ref::new(term)
} else {
log::error!("unknown layout {term}");
return ExitCode::FAILURE;
}
}
None => match default_layout_ref {
DefaultLayoutRef::Some(layout_ref) => layout_ref,
_ => {
log::error!("missing layout");
return ExitCode::FAILURE;
}
},
};

let gen_options = treeldr_gen_rust::Options::new();

let result =
treeldr_gen_rust::generate(RdfContext::default(), &layouts, &layout_ref, &gen_options);

match result {
Ok(r) => {
println!("{r}");
ExitCode::SUCCESS
}
Err(e) => {
log::error!("parse error: {e}");
ExitCode::FAILURE
}
}
}
Loading

0 comments on commit 3d4e745

Please sign in to comment.