mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
Have bindgen CLI accept an output path
This commit is contained in:
parent
882e1a7c29
commit
2ed35e8a04
1 changed files with 84 additions and 20 deletions
|
@ -1,46 +1,110 @@
|
||||||
use clap::{ArgEnum, Parser};
|
use clap::Parser;
|
||||||
use std::io::ErrorKind;
|
use roc_bindgen::bindgen_rs;
|
||||||
|
use roc_bindgen::load::load_types;
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{ErrorKind, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{fs, process};
|
use std::process;
|
||||||
|
|
||||||
#[derive(Clone, Debug, ArgEnum)]
|
/// Printed in error messages if you try to use an unsupported extension.
|
||||||
enum TargetFormat {
|
const SUPPORTED_EXTENSIONS: &str = ".c, .rs, .zig, and .json";
|
||||||
Rust,
|
|
||||||
Json,
|
|
||||||
C,
|
|
||||||
Zig,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO add an option for --targets so that you can specify
|
// TODO add an option for --targets so that you can specify
|
||||||
// e.g. 64-bit, 32-bit, *and* 16-bit (which can matter for alignment because of pointers)
|
// e.g. 64-bit, 32-bit, *and* 16-bit (which can matter for alignment because of pointers)
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[clap(about)]
|
#[clap(about)]
|
||||||
struct Opts {
|
struct Opts {
|
||||||
/// The output format
|
|
||||||
#[clap(arg_enum)]
|
|
||||||
target: TargetFormat,
|
|
||||||
|
|
||||||
/// The path to the platform's Package-Config.roc file
|
/// The path to the platform's Package-Config.roc file
|
||||||
platform_module: PathBuf,
|
platform_module: PathBuf,
|
||||||
|
|
||||||
|
/// The output file, e.g. `test.rs`
|
||||||
|
dest: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum OutputType {
|
||||||
|
Rust,
|
||||||
|
C,
|
||||||
|
Zig,
|
||||||
|
Json,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let opts = Opts::parse();
|
let opts = Opts::parse();
|
||||||
let path = opts.platform_module;
|
let input_path = opts.platform_module;
|
||||||
|
let cwd = std::env::current_dir().unwrap();
|
||||||
|
let output_path = opts.dest;
|
||||||
|
let output_type = match output_path.extension().and_then(OsStr::to_str) {
|
||||||
|
Some("rs") => OutputType::Rust,
|
||||||
|
Some("c") => OutputType::C,
|
||||||
|
Some("zig") => OutputType::Zig,
|
||||||
|
Some("json") => OutputType::Json,
|
||||||
|
Some(other) => {
|
||||||
|
eprintln!(
|
||||||
|
"Unsupported output file extension: \".{}\" - currently supported extensions are {}",
|
||||||
|
other,
|
||||||
|
SUPPORTED_EXTENSIONS
|
||||||
|
);
|
||||||
|
|
||||||
match fs::read_to_string(&path) {
|
process::exit(1);
|
||||||
Ok(src) => {
|
}
|
||||||
println!("Got this source: {:?}", src);
|
None => {
|
||||||
|
eprintln!("The output file path needs to have a file extension in order to tell what output format to use. Currently supported extensions are {}", SUPPORTED_EXTENSIONS);
|
||||||
|
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match load_types(input_path.clone(), &cwd) {
|
||||||
|
Ok(types) => {
|
||||||
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
let result = match output_type {
|
||||||
|
OutputType::Rust => bindgen_rs::write_types(&types, &mut buf),
|
||||||
|
OutputType::C => todo!("TODO: Generate bindings for C"),
|
||||||
|
OutputType::Zig => todo!("TODO: Generate bindings for Zig"),
|
||||||
|
OutputType::Json => todo!("TODO: Generate bindings for JSON"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(err) = result {
|
||||||
|
eprintln!(
|
||||||
|
"Unable to generate binding string {} - {:?}",
|
||||||
|
output_path.display(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = File::create(output_path.clone()).unwrap_or_else(|err| {
|
||||||
|
eprintln!(
|
||||||
|
"Unable to create output file {} - {:?}",
|
||||||
|
output_path.display(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
|
||||||
|
process::exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
file.write_all(buf.as_bytes()).unwrap_or_else(|err| {
|
||||||
|
eprintln!(
|
||||||
|
"Unable to write bindings to output file {} - {:?}",
|
||||||
|
output_path.display(),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
|
||||||
|
process::exit(1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Err(err) => match err.kind() {
|
Err(err) => match err.kind() {
|
||||||
ErrorKind::NotFound => {
|
ErrorKind::NotFound => {
|
||||||
eprintln!("Platform module file not found: {}", path.display());
|
eprintln!("Platform module file not found: {}", input_path.display());
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
error => {
|
error => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Error loading platform module file {} - {:?}",
|
"Error loading platform module file {} - {:?}",
|
||||||
path.display(),
|
input_path.display(),
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue