Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use camino::Utf8PathBuf;
use clap::{Parser, Subcommand};
use uniffi_bindgen::bindings::TargetLanguage;
use uniffi_bindgen::BindingGeneratorDefault;
// Structs to help our cmdline parsing. Note that docstrings below form part
// of the "help" output.
/// Scaffolding and bindings generator for Rust
#[derive(Parser)]
#[clap(name = "uniffi-bindgen")]
#[clap(version = clap::crate_version!())]
#[clap(propagate_version = true)]
struct Cli {
#[clap(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Generate foreign language bindings
Generate {
/// Foreign language(s) for which to build bindings.
#[clap(long, short, value_enum)]
language: Vec<TargetLanguage>,
/// Directory in which to write generated files. Default is same folder as .udl file.
#[clap(long, short)]
out_dir: Option<Utf8PathBuf>,
/// Do not try to format the generated bindings.
#[clap(long, short)]
no_format: bool,
/// Path to optional uniffi config file. This config is merged with the `uniffi.toml` config present in each crate, with its values taking precedence.
#[clap(long, short)]
config: Option<Utf8PathBuf>,
/// Extract proc-macro metadata from a native lib (cdylib or staticlib) for this crate.
#[clap(long)]
lib_file: Option<Utf8PathBuf>,
/// Pass in a cdylib path rather than a UDL file
#[clap(long = "library")]
library_mode: bool,
/// When `--library` is passed, only generate bindings for one crate.
/// When `--library` is not passed, use this as the crate name instead of attempting to
/// locate and parse Cargo.toml.
#[clap(long = "crate")]
crate_name: Option<String>,
/// Path to the UDL file, or cdylib if `library-mode` is specified
source: Utf8PathBuf,
},
/// Generate Rust scaffolding code
Scaffolding {
/// Directory in which to write generated files. Default is same folder as .udl file.
#[clap(long, short)]
out_dir: Option<Utf8PathBuf>,
/// Do not try to format the generated bindings.
#[clap(long, short)]
no_format: bool,
/// Path to the UDL file.
udl_file: Utf8PathBuf,
},
/// Print a debug representation of the interface from a dynamic library
PrintRepr {
/// Path to the library file (.so, .dll, .dylib, or .a)
path: Utf8PathBuf,
},
}
pub fn run_main() -> anyhow::Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Generate {
language,
out_dir,
no_format,
config,
lib_file,
source,
crate_name,
library_mode,
} => {
if library_mode {
if lib_file.is_some() {
panic!("--lib-file is not compatible with --library.")
}
let out_dir = out_dir.expect("--out-dir is required when using --library");
if language.is_empty() {
panic!("please specify at least one language with --language")
}
uniffi_bindgen::library_mode::generate_bindings(
&source,
crate_name,
&BindingGeneratorDefault {
target_languages: language,
try_format_code: !no_format,
},
config.as_deref(),
&out_dir,
!no_format,
)?;
} else {
uniffi_bindgen::generate_bindings(
&source,
config.as_deref(),
BindingGeneratorDefault {
target_languages: language,
try_format_code: !no_format,
},
out_dir.as_deref(),
lib_file.as_deref(),
crate_name.as_deref(),
!no_format,
)?;
}
}
Commands::Scaffolding {
out_dir,
no_format,
udl_file,
} => {
uniffi_bindgen::generate_component_scaffolding(
&udl_file,
out_dir.as_deref(),
!no_format,
)?;
}
Commands::PrintRepr { path } => {
uniffi_bindgen::print_repr(&path)?;
}
};
Ok(())
}