use cargo_metadata::MetadataCommand;
use once_cell::sync::Lazy;
use syn::Path;
static ETHERS_CRATES: Lazy<(&'static str, &'static str, &'static str)> =
Lazy::new(determine_ethers_crates);
pub fn ethers_core_crate() -> Path {
syn::parse_str(ETHERS_CRATES.0).expect("valid path; qed")
}
pub fn ethers_contract_crate() -> Path {
syn::parse_str(ETHERS_CRATES.1).expect("valid path; qed")
}
pub fn ethers_providers_crate() -> Path {
syn::parse_str(ETHERS_CRATES.2).expect("valid path; qed")
}
pub fn determine_ethers_crates() -> (&'static str, &'static str, &'static str) {
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR");
let manifest_dir = if let Ok(manifest_dir) = manifest_dir {
manifest_dir
} else {
return ("ethers::core", "ethers::contract", "ethers::providers")
};
let lock_file = format!("{manifest_dir}/Cargo.lock");
let needs_lock_file_cleanup = !std::path::Path::new(&lock_file).exists();
let res = MetadataCommand::new()
.manifest_path(&format!("{manifest_dir}/Cargo.toml"))
.exec()
.ok()
.and_then(|metadata| {
metadata.root_package().and_then(|pkg| {
let sub_crates = Some(("ethers_core", "ethers_contract", "ethers_providers"));
if [
"ethers-contract",
"ethers-derive-eip712",
"ethers-signers",
"ethers-middleware",
"ethers-solc",
]
.contains(&pkg.name.as_str())
{
return sub_crates
}
let mut has_ethers_core = false;
let mut has_ethers_contract = false;
let mut has_ethers_providers = false;
for dep in pkg.dependencies.iter() {
match dep.name.as_str() {
"ethers-core" => {
has_ethers_core = true;
}
"ethers-contract" => {
has_ethers_contract = true;
}
"ethers-providers" => {
has_ethers_providers = true;
}
"ethers" => return None,
_ => {}
}
}
if has_ethers_core && has_ethers_contract && has_ethers_providers {
return sub_crates
}
None
})
})
.unwrap_or(("ethers::core", "ethers::contract", "ethers::providers"));
if needs_lock_file_cleanup {
let _ = std::fs::remove_file(lock_file);
}
res
}