Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust generator v0.2 #162

Merged
merged 10 commits into from
Dec 8, 2023
Merged
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