Skip to content
This repository was archived by the owner on Oct 19, 2024. It is now read-only.

Commit e23b959

Browse files
committed
feat(solc): add remove_contract utility function
1 parent 73d3d3f commit e23b959

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

Diff for: ethers-solc/src/compile/output/info.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Commonly used identifiers for contracts in the compiled output
2-
use std::{convert::TryFrom, fmt, str::FromStr};
2+
use std::{borrow::Cow, convert::TryFrom, fmt, str::FromStr};
33

44
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
55
#[error("{0}")]
@@ -77,6 +77,39 @@ impl From<FullContractInfo> for ContractInfo {
7777
}
7878
}
7979

80+
/// The reference type for `ContractInfo`
81+
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
82+
pub struct ContractInfoRef<'a> {
83+
pub path: Option<Cow<'a, str>>,
84+
pub name: Cow<'a, str>,
85+
}
86+
87+
impl<'a> From<ContractInfo> for ContractInfoRef<'a> {
88+
fn from(info: ContractInfo) -> Self {
89+
ContractInfoRef { path: info.path.map(Into::into), name: info.name.into() }
90+
}
91+
}
92+
93+
impl<'a> From<&'a ContractInfo> for ContractInfoRef<'a> {
94+
fn from(info: &'a ContractInfo) -> Self {
95+
ContractInfoRef {
96+
path: info.path.as_deref().map(Into::into),
97+
name: info.name.as_str().into(),
98+
}
99+
}
100+
}
101+
impl<'a> From<FullContractInfo> for ContractInfoRef<'a> {
102+
fn from(info: FullContractInfo) -> Self {
103+
ContractInfoRef { path: Some(info.path.into()), name: info.name.into() }
104+
}
105+
}
106+
107+
impl<'a> From<&'a FullContractInfo> for ContractInfoRef<'a> {
108+
fn from(info: &'a FullContractInfo) -> Self {
109+
ContractInfoRef { path: Some(info.path.as_str().into()), name: info.name.as_str().into() }
110+
}
111+
}
112+
80113
/// Represents the common contract argument pattern `<path>:<contractname>`
81114
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
82115
pub struct FullContractInfo {

Diff for: ethers-solc/src/compile/output/mod.rs

+33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
Error,
77
},
88
buildinfo::RawBuildInfo,
9+
info::ContractInfoRef,
910
sources::{VersionedSourceFile, VersionedSourceFiles},
1011
ArtifactId, ArtifactOutput, Artifacts, CompilerOutput, ConfigurableArtifacts, SolcIoError,
1112
};
@@ -378,6 +379,38 @@ impl AggregatedCompilerOutput {
378379
self.contracts.remove(path, contract)
379380
}
380381

382+
/// Removes the contract with matching path and name using the `<path>:<contractname>` pattern
383+
/// where `path` is optional.
384+
///
385+
/// If the `path` segment is `None`, then the first matching `Contract` is returned, see
386+
/// [Self::remove_first]
387+
///
388+
///
389+
///
390+
/// # Example
391+
///
392+
/// ```
393+
/// use ethers_solc::Project;
394+
/// use ethers_solc::artifacts::*;
395+
/// use ethers_solc::info::ContractInfo;
396+
/// # fn demo(project: Project) {
397+
/// let mut output = project.compile().unwrap().output();
398+
/// let info = ContractInfo::new("src/Greeter.sol:Greeter");
399+
/// let contract = output.remove_contract(&info).unwrap();
400+
/// # }
401+
/// ```
402+
pub fn remove_contract<'a>(
403+
&mut self,
404+
info: impl Into<ContractInfoRef<'a>>,
405+
) -> Option<Contract> {
406+
let ContractInfoRef { path, name } = info.into();
407+
if let Some(path) = path {
408+
self.remove(path, name)
409+
} else {
410+
self.remove_first(name)
411+
}
412+
}
413+
381414
/// Iterate over all contracts and their names
382415
pub fn contracts_iter(&self) -> impl Iterator<Item = (&String, &Contract)> {
383416
self.contracts.contracts()

Diff for: ethers-solc/tests/project.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use ethers_solc::{
1515
},
1616
buildinfo::BuildInfo,
1717
cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME},
18+
info::ContractInfo,
1819
project_util::*,
1920
remappings::Remapping,
2021
CompilerInput, ConfigurableArtifacts, ExtraOutputValues, Graph, Project, ProjectCompileOutput,
@@ -1546,9 +1547,16 @@ fn can_compile_sparse_with_link_references() {
15461547
let lib = dup.remove_first("MyLib");
15471548
assert!(lib.is_none());
15481549

1549-
let lib = output.remove(my_lib_path.to_string_lossy(), "MyLib");
1550+
dup = output.clone();
1551+
let lib = dup.remove(my_lib_path.to_string_lossy(), "MyLib");
15501552
assert!(lib.is_some());
1551-
let lib = output.remove(my_lib_path.to_string_lossy(), "MyLib");
1553+
let lib = dup.remove(my_lib_path.to_string_lossy(), "MyLib");
1554+
assert!(lib.is_none());
1555+
1556+
let info = ContractInfo::new(format!("{}:{}", my_lib_path.to_string_lossy(), "MyLib"));
1557+
let lib = output.remove_contract(&info);
1558+
assert!(lib.is_some());
1559+
let lib = output.remove_contract(&info);
15521560
assert!(lib.is_none());
15531561
}
15541562

0 commit comments

Comments
 (0)