Skip to content

Commit

Permalink
Expose the find_components function
Browse files Browse the repository at this point in the history
The generate_bindings docs mentioned wanting to expose a function that
just finds ComponentInterface and config tables for each component and
leaves the rest to the external bindings generator.  This is exactly
what I want to use for uniffi-bindgen-gecko-js.

The `find_components` function was pretty much exactly what we wanted.
I made some minor changes to it and exposed it as a pub function.
  • Loading branch information
bendk committed Aug 7, 2024
1 parent 7ff7584 commit 06f10d0
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
7 changes: 4 additions & 3 deletions uniffi_bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ use crate::interface::{
Variant,
};
pub use interface::ComponentInterface;
pub use library_mode::find_components;
use scaffolding::RustScaffolding;
use uniffi_meta::Type;

Expand Down Expand Up @@ -297,7 +298,8 @@ pub fn generate_external_bindings<T: BindingGenerator>(
let config = {
let crate_config = load_toml_file(Some(&crate_root.join("uniffi.toml")))
.context("failed to load {crate_root}/uniffi.toml")?;
let toml_value = overridden_config_value(crate_config, config_file_override)?;
let toml_value =
overridden_config_value(crate_config.unwrap_or_default(), config_file_override)?;
binding_generator.new_config(&toml_value)?
};

Expand Down Expand Up @@ -497,10 +499,9 @@ fn load_toml_file(source: Option<&Utf8Path>) -> Result<Option<toml::value::Table

/// Load the default `uniffi.toml` config, merge TOML trees with `config_file_override` if specified.
fn overridden_config_value(
config: Option<toml::value::Table>,
mut config: toml::value::Table,
config_file_override: Option<&Utf8Path>,
) -> Result<toml::Value> {
let mut config = config.unwrap_or_default();
let override_config = load_toml_file(config_file_override).context("override config")?;
if let Some(override_config) = override_config {
merge_toml(&mut config, override_config);
Expand Down
34 changes: 22 additions & 12 deletions uniffi_bindgen/src/library_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ use crate::{
use anyhow::bail;
use camino::Utf8Path;
use std::{collections::HashMap, fs};
use toml::value::Table as TomlTable;
use uniffi_meta::{
create_metadata_groups, fixup_external_type, group_metadata, Metadata, MetadataGroup,
};

/// Generate foreign bindings
///
/// This replicates the current process used for generating the builtin bindings.
/// External bindings authors should consider using [find_components], which provides a simpler
/// interface and allows for more flexibility in how the external bindings are generated.
///
/// Returns the list of sources used to generate the bindings, in no particular order.
// XXX - we should consider killing this function and replace it with a function
// which just locates the `Components` and returns them, leaving the filtering
// and actual generation to the callers, which also would allow removing the potentially
// confusing crate_name param.
pub fn generate_bindings<T: BindingGenerator + ?Sized>(
library_path: &Utf8Path,
crate_name: Option<String>,
Expand All @@ -42,11 +43,10 @@ pub fn generate_bindings<T: BindingGenerator + ?Sized>(
out_dir: &Utf8Path,
try_format_code: bool,
) -> Result<Vec<Component<T::Config>>> {
let mut components = find_components(config_supplier, library_path)?
let mut components = find_components(library_path, config_supplier)?
.into_iter()
.map(|ci| {
let crate_toml = config_supplier.get_toml(ci.crate_name())?;
let toml_value = overridden_config_value(crate_toml, config_file_override)?;
.map(|Component { ci, config }| {
let toml_value = overridden_config_value(config, config_file_override)?;
let config = binding_generator.new_config(&toml_value)?;
Ok(Component { ci, config })
})
Expand Down Expand Up @@ -90,10 +90,17 @@ pub fn calc_cdylib_name(library_path: &Utf8Path) -> Option<&str> {
None
}

fn find_components(
config_supplier: &dyn BindgenCrateConfigSupplier,
/// Find UniFFI components from a shared library file
///
/// This method inspects the library file and creates [ComponentInterface] instances for each
/// component used to build it. It parses the UDL files from `uniffi::include_scaffolding!` macro
/// calls.
///
/// `config_supplier` is used to find UDL files on disk and load config data.
pub fn find_components(
library_path: &Utf8Path,
) -> Result<Vec<ComponentInterface>> {
config_supplier: &dyn BindgenCrateConfigSupplier,
) -> Result<Vec<Component<TomlTable>>> {
let items = macro_metadata::extract_from_library(library_path)?;
let mut metadata_groups = create_metadata_groups(&items);
group_metadata(&mut metadata_groups, items)?;
Expand Down Expand Up @@ -128,7 +135,10 @@ fn find_components(
ci.add_metadata(metadata)?;
};
ci.add_metadata(group)?;
Ok(ci)
let config = config_supplier
.get_toml(ci.crate_name())?
.unwrap_or_default();
Ok(Component { ci, config })
})
.collect()
}
Expand Down

0 comments on commit 06f10d0

Please sign in to comment.