use std::fs;
use anyhow::bail;
use camino::Utf8PathBuf;
use crate::Result;
#[derive(Default)]
pub struct BindgenPaths {
layers: Vec<Box<dyn BindgenPathsLayer>>,
}
impl BindgenPaths {
#[cfg(feature = "cargo-metadata")]
pub fn add_cargo_metadata_layer(&mut self, no_deps: bool) -> Result<()> {
self.add_layer(
crate::cargo_metadata::CrateConfigSupplier::from_cargo_metadata_command(no_deps)?,
);
Ok(())
}
pub fn add_layer(&mut self, layer: impl BindgenPathsLayer + 'static) {
self.layers.push(Box::new(layer));
}
pub fn get_crate_root(&self, crate_name: &str) -> Option<Utf8PathBuf> {
self.layers
.iter()
.find_map(|l| l.get_crate_root(crate_name))
}
pub fn get_config_path(&self, crate_name: &str) -> Option<Utf8PathBuf> {
self.layers
.iter()
.find_map(|l| l.get_config_path(crate_name))
}
pub fn get_udl_path(&self, crate_name: &str, udl_name: &str) -> Option<Utf8PathBuf> {
self.layers
.iter()
.find_map(|l| l.get_udl_path(crate_name, udl_name))
}
pub fn get_udl(&self, crate_name: &str, udl_name: &str) -> Result<String> {
match self.get_udl_path(crate_name, udl_name) {
Some(path) => Ok(fs::read_to_string(path)?),
None => bail!("UDL file {udl_name:?} not found for crate {crate_name:?}"),
}
}
}
pub trait BindgenPathsLayer {
fn get_crate_root(&self, _crate_name: &str) -> Option<Utf8PathBuf> {
None
}
fn get_config_path(&self, crate_name: &str) -> Option<Utf8PathBuf> {
self.get_crate_root(crate_name)
.map(|root| root.join("uniffi.toml"))
}
fn get_udl_path(&self, crate_name: &str, udl_name: &str) -> Option<Utf8PathBuf> {
self.get_crate_root(crate_name)
.map(|root| root.join("src").join(format!("{udl_name}.udl")))
}
}