/* 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; // 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, /// Directory in which to write generated files. Default is same folder as .udl file. #[clap(long, short)] out_dir: Option, /// Do not try to format the generated bindings. #[clap(long, short)] no_format: bool, /// Path to the optional uniffi config file. If not provided, uniffi-bindgen will try to guess it from the UDL's file location. #[clap(long, short)] config: Option, /// Extract proc-macro metadata from a native lib (cdylib or staticlib) for this crate. #[clap(long)] lib_file: Option, /// 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, /// 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, /// 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.") } if config.is_some() { panic!("--config is not compatible with --library. The config file(s) will be found automatically.") } 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, &language, &out_dir, !no_format, )?; } else { uniffi_bindgen::generate_bindings( &source, config.as_deref(), language, 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(()) }