diff --git a/Cargo.lock b/Cargo.lock index e5b612f8..78338021 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1111,6 +1111,7 @@ dependencies = [ "syn", "tempfile", "url", + "walkdir", ] [[package]] diff --git a/ethers-contract/ethers-contract-abigen/Cargo.toml b/ethers-contract/ethers-contract-abigen/Cargo.toml index 3bcb70a9..ef9b3a9a 100644 --- a/ethers-contract/ethers-contract-abigen/Cargo.toml +++ b/ethers-contract/ethers-contract-abigen/Cargo.toml @@ -25,6 +25,7 @@ reqwest = { version = "0.11.3", default-features = false, features = ["blocking" once_cell = "1.8.0" cfg-if = "1.0.0" dunce = "1.0.2" +walkdir = "2.3.2" [target.'cfg(target_arch = "wasm32")'.dependencies] # NOTE: this enables wasm compatibility for getrandom indirectly diff --git a/ethers-contract/ethers-contract-abigen/src/lib.rs b/ethers-contract/ethers-contract-abigen/src/lib.rs index ea4bfd1d..5df72810 100644 --- a/ethers-contract/ethers-contract-abigen/src/lib.rs +++ b/ethers-contract/ethers-contract-abigen/src/lib.rs @@ -266,12 +266,9 @@ impl MultiAbigen { /// ``` pub fn from_json_files(dir: impl AsRef) -> Result { let mut abis = Vec::new(); - for file in fs::read_dir(dir)?.into_iter().filter_map(std::io::Result::ok).filter(|p| { - p.path().is_file() && p.path().extension().and_then(|ext| ext.to_str()) == Some("json") - }) { - let file: fs::DirEntry = file; - if let Some(file_name) = file.path().file_stem().and_then(|s| s.to_str()) { - let content = fs::read_to_string(file.path())?; + for file in util::json_files(dir) { + if let Some(file_name) = file.file_stem().and_then(|s| s.to_str()) { + let content = fs::read_to_string(&file)?; abis.push((file_name.to_string(), content)); } } diff --git a/ethers-contract/ethers-contract-abigen/src/util.rs b/ethers-contract/ethers-contract-abigen/src/util.rs index f8858db4..7a779990 100644 --- a/ethers-contract/ethers-contract-abigen/src/util.rs +++ b/ethers-contract/ethers-contract-abigen/src/util.rs @@ -151,6 +151,17 @@ fn take_while(s: &str, mut predicate: impl FnMut(char) -> bool) -> (&str, &str) s.split_at(index) } +/// Returns a list of absolute paths to all the json files under the root +pub fn json_files(root: impl AsRef) -> Vec { + walkdir::WalkDir::new(root) + .into_iter() + .filter_map(Result::ok) + .filter(|e| e.file_type().is_file()) + .filter(|e| e.path().extension().map(|ext| ext == "json").unwrap_or_default()) + .map(|e| e.path().into()) + .collect() +} + #[cfg(test)] mod tests { use super::*;