use std::path::Path;
use abi_stable::library::RootModule;
use datafusion_common::{DataFusionError, Result};
use crate::tests::ForeignLibraryModuleRef;
pub fn compute_library_path<M: RootModule>(
target_path: &Path,
) -> std::io::Result<std::path::PathBuf> {
let debug_dir = target_path.join("debug");
let release_dir = target_path.join("release");
let ci_dir = target_path.join("ci");
let debug_path = M::get_library_path(&debug_dir.join("deps"));
let release_path = M::get_library_path(&release_dir.join("deps"));
let ci_path = M::get_library_path(&ci_dir.join("deps"));
let all_paths = vec![
(debug_dir.clone(), debug_path),
(release_dir, release_path),
(ci_dir, ci_path),
];
let best_path = all_paths
.into_iter()
.filter(|(_, path)| path.exists())
.filter_map(|(dir, path)| path.metadata().map(|m| (dir, m)).ok())
.filter_map(|(dir, meta)| meta.modified().map(|m| (dir, m)).ok())
.max_by_key(|(_, date)| *date)
.map(|(dir, _)| dir)
.unwrap_or(debug_dir);
Ok(best_path)
}
pub fn get_module() -> Result<ForeignLibraryModuleRef> {
let expected_version = crate::version();
let crate_root = Path::new(env!("CARGO_MANIFEST_DIR"));
let target_dir = crate_root
.parent()
.expect("Failed to find crate parent")
.parent()
.expect("Failed to find workspace root")
.join("target");
let library_path =
compute_library_path::<ForeignLibraryModuleRef>(target_dir.as_path())
.map_err(|e| DataFusionError::External(Box::new(e)))?
.join("deps");
let module = ForeignLibraryModuleRef::load_from_directory(&library_path)
.map_err(|e| DataFusionError::External(Box::new(e)))?;
assert_eq!(
module
.version()
.expect("Unable to call version on FFI module")(),
expected_version
);
Ok(module)
}