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

Commit 81ecd87

Browse files
committed
feat!(solc): add additional remove functions
1 parent c2f5a87 commit 81ecd87

File tree

5 files changed

+98
-16
lines changed

5 files changed

+98
-16
lines changed

Diff for: ethers-solc/src/artifacts/contract.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl ContractBytecode {
8989
/// use ethers_solc::artifacts::*;
9090
/// # fn demo(project: Project) {
9191
/// let mut output = project.compile().unwrap().output();
92-
/// let contract: ContractBytecode = output.remove("Greeter").unwrap().into();
92+
/// let contract: ContractBytecode = output.remove_first("Greeter").unwrap().into();
9393
/// let contract = contract.unwrap();
9494
/// # }
9595
/// ```
@@ -312,7 +312,7 @@ impl CompactContract {
312312
/// use ethers_solc::artifacts::*;
313313
/// # fn demo(project: Project) {
314314
/// let mut output = project.compile().unwrap().output();
315-
/// let contract: CompactContract = output.remove("Greeter").unwrap().into();
315+
/// let contract: CompactContract = output.remove_first("Greeter").unwrap().into();
316316
/// let contract = contract.unwrap();
317317
/// # }
318318
/// ```

Diff for: ethers-solc/src/artifacts/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@ pub struct Metadata {
858858

859859
/// A helper type that ensures lossless (de)serialisation so we can preserve the exact String
860860
/// metadata value that's being hashed by solc
861-
#[derive(Clone, Debug, PartialEq)]
861+
#[derive(Clone, Debug, PartialEq, Eq)]
862862
pub struct LosslessMetadata {
863863
/// The complete abi as json value
864864
pub raw_metadata: String,

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

+40-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ impl VersionedContracts {
5353
/// use ethers_solc::artifacts::*;
5454
/// # fn demo(project: Project) {
5555
/// let (_, mut contracts) = project.compile().unwrap().output().split();
56-
/// let contract = contracts.remove("Greeter").unwrap();
56+
/// let contract = contracts.remove_first("Greeter").unwrap();
5757
/// # }
5858
/// ```
59-
pub fn remove(&mut self, contract: impl AsRef<str>) -> Option<Contract> {
59+
pub fn remove_first(&mut self, contract: impl AsRef<str>) -> Option<Contract> {
6060
let contract_name = contract.as_ref();
6161
self.0.values_mut().find_map(|all_contracts| {
6262
let mut contract = None;
@@ -72,11 +72,47 @@ impl VersionedContracts {
7272
})
7373
}
7474

75+
/// Removes the contract with matching path and name
76+
///
77+
/// # Example
78+
///
79+
/// ```
80+
/// use ethers_solc::Project;
81+
/// use ethers_solc::artifacts::*;
82+
/// # fn demo(project: Project) {
83+
/// let (_, mut contracts) = project.compile().unwrap().output().split();
84+
/// let contract = contracts.remove("src/Greeter.sol", "Greeter").unwrap();
85+
/// # }
86+
/// ```
87+
pub fn remove(&mut self, path: impl AsRef<str>, contract: impl AsRef<str>) -> Option<Contract> {
88+
let contract_name = contract.as_ref();
89+
let (key, mut all_contracts) = self.0.remove_entry(path.as_ref())?;
90+
let mut contract = None;
91+
if let Some((c, mut contracts)) = all_contracts.remove_entry(contract_name) {
92+
if !contracts.is_empty() {
93+
contract = Some(contracts.remove(0).contract);
94+
}
95+
if !contracts.is_empty() {
96+
all_contracts.insert(c, contracts);
97+
}
98+
}
99+
100+
if !all_contracts.is_empty() {
101+
self.0.insert(key, all_contracts);
102+
}
103+
contract
104+
}
105+
75106
/// Given the contract file's path and the contract's name, tries to return the contract's
76107
/// bytecode, runtime bytecode, and abi
77-
pub fn get(&self, path: &str, contract: &str) -> Option<CompactContractRef> {
108+
pub fn get(
109+
&self,
110+
path: impl AsRef<str>,
111+
contract: impl AsRef<str>,
112+
) -> Option<CompactContractRef> {
113+
let contract = contract.as_ref();
78114
self.0
79-
.get(path)
115+
.get(path.as_ref())
80116
.and_then(|contracts| {
81117
contracts.get(contract).and_then(|c| c.get(0).map(|c| &c.contract))
82118
})

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

+34-4
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,27 @@ impl AggregatedCompilerOutput {
354354
/// use ethers_solc::artifacts::*;
355355
/// # fn demo(project: Project) {
356356
/// let mut output = project.compile().unwrap().output();
357-
/// let contract = output.remove("Greeter").unwrap();
357+
/// let contract = output.remove_first("Greeter").unwrap();
358358
/// # }
359359
/// ```
360-
pub fn remove(&mut self, contract: impl AsRef<str>) -> Option<Contract> {
361-
self.contracts.remove(contract)
360+
pub fn remove_first(&mut self, contract: impl AsRef<str>) -> Option<Contract> {
361+
self.contracts.remove_first(contract)
362+
}
363+
364+
/// Removes the contract with matching path and name
365+
///
366+
/// # Example
367+
///
368+
/// ```
369+
/// use ethers_solc::Project;
370+
/// use ethers_solc::artifacts::*;
371+
/// # fn demo(project: Project) {
372+
/// let mut output = project.compile().unwrap().output();
373+
/// let contract = output.remove("src/Greeter.sol", "Greeter").unwrap();
374+
/// # }
375+
/// ```
376+
pub fn remove(&mut self, path: impl AsRef<str>, contract: impl AsRef<str>) -> Option<Contract> {
377+
self.contracts.remove(path, contract)
362378
}
363379

364380
/// Iterate over all contracts and their names
@@ -373,7 +389,21 @@ impl AggregatedCompilerOutput {
373389

374390
/// Given the contract file's path and the contract's name, tries to return the contract's
375391
/// bytecode, runtime bytecode, and abi
376-
pub fn get(&self, path: &str, contract: &str) -> Option<CompactContractRef> {
392+
/// # Example
393+
///
394+
/// ```
395+
/// use ethers_solc::Project;
396+
/// use ethers_solc::artifacts::*;
397+
/// # fn demo(project: Project) {
398+
/// let output = project.compile().unwrap().output();
399+
/// let contract = output.get("src/Greeter.sol", "Greeter").unwrap();
400+
/// # }
401+
/// ```
402+
pub fn get(
403+
&self,
404+
path: impl AsRef<str>,
405+
contract: impl AsRef<str>,
406+
) -> Option<CompactContractRef> {
377407
self.contracts.get(path, contract)
378408
}
379409

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

+21-5
Original file line numberDiff line numberDiff line change
@@ -1516,24 +1516,40 @@ fn can_compile_sparse_with_link_references() {
15161516
)
15171517
.unwrap();
15181518

1519-
tmp.add_source(
1520-
"mylib.sol",
1521-
r#"
1519+
let my_lib_path = tmp
1520+
.add_source(
1521+
"mylib.sol",
1522+
r#"
15221523
pragma solidity =0.8.12;
15231524
library MyLib {
15241525
function doStuff() external pure returns (uint256) {return 1337;}
15251526
}
15261527
"#,
1527-
)
1528-
.unwrap();
1528+
)
1529+
.unwrap();
15291530

15301531
let mut compiled = tmp.compile_sparse(TestFileFilter::default()).unwrap();
15311532
assert!(!compiled.has_compiler_errors());
15321533

1534+
let mut output = compiled.clone().output();
1535+
15331536
assert!(compiled.find("ATest").is_some());
15341537
assert!(compiled.find("MyLib").is_some());
15351538
let lib = compiled.remove("MyLib").unwrap();
15361539
assert!(lib.bytecode.is_some());
1540+
let lib = compiled.remove("MyLib");
1541+
assert!(lib.is_none());
1542+
1543+
let mut dup = output.clone();
1544+
let lib = dup.remove_first("MyLib");
1545+
assert!(lib.is_some());
1546+
let lib = dup.remove_first("MyLib");
1547+
assert!(lib.is_none());
1548+
1549+
let lib = output.remove(my_lib_path.to_string_lossy(), "MyLib");
1550+
assert!(lib.is_some());
1551+
let lib = output.remove(my_lib_path.to_string_lossy(), "MyLib");
1552+
assert!(lib.is_none());
15371553
}
15381554

15391555
#[test]

0 commit comments

Comments
 (0)