use anyhow::{anyhow, Result};
use argh::FromArgs;
use dart_bindgen::{config::*, Codegen};
use std::{path::PathBuf, str::FromStr};
#[derive(Debug, FromArgs)]
struct Args {
#[argh(option, short = 'i')]
input: PathBuf,
#[argh(option, short = 'o')]
output: Option<PathBuf>,
#[argh(switch)]
allo_isolate: bool,
#[argh(option)]
name: Option<String>,
#[argh(option)]
android: Option<CreationMode>,
#[argh(option)]
fuchsia: Option<CreationMode>,
#[argh(option)]
ios: Option<CreationMode>,
#[argh(option)]
linux: Option<CreationMode>,
#[argh(option)]
macos: Option<CreationMode>,
#[argh(option)]
windows: Option<CreationMode>,
}
#[derive(Debug, Clone)]
struct CreationMode(DynamicLibraryCreationMode);
impl FromStr for CreationMode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
use DynamicLibraryCreationMode::*;
match s {
"executable" => Ok(Self(Executable)),
"process" => Ok(Self(Process)),
path => Ok(Self(Open(path.to_owned()))),
}
}
}
macro_rules! into_mode {
($m:expr) => {
match $m {
Some(v) => Some(DynamicLibraryPlatformConfig::new(v.0)),
_ => None,
}
};
}
fn main() -> Result<()> {
pretty_env_logger::init();
let args: Args = argh::from_env();
let config = DynamicLibraryConfig {
android: into_mode!(args.android),
fuchsia: into_mode!(args.fuchsia),
ios: into_mode!(args.ios),
linux: into_mode!(args.linux),
macos: into_mode!(args.macos),
windows: into_mode!(args.windows),
};
let output_path = match args.output {
Some(v) => v,
None => {
let mut path = args.input.clone();
path.set_extension("dart");
path
},
};
let name = match args.name {
Some(v) => v,
None => args
.input
.file_stem()
.map(|name| format!("lib{}", name.to_string_lossy()))
.ok_or_else(|| anyhow!("Could't make the libname"))?,
};
let mut builder = Codegen::builder()
.with_lib_name(name)
.with_src_header(args.input)
.with_config(config);
if args.allo_isolate {
builder = builder.with_allo_isolate();
}
let codegen = builder.build()?;
let bindings = codegen.generate()?;
bindings.write_to_file(output_path)?;
Ok(())
}