@@ -8,8 +8,9 @@ use eyre::{OptionExt, Result};
8
8
use foundry_compilers:: {
9
9
ArtifactId , Project , ProjectCompileOutput ,
10
10
artifacts:: {
11
- BytecodeObject , CompactBytecode , CompactContractBytecode , CompactDeployedBytecode ,
12
- ConfigurableContractArtifact , ContractBytecodeSome , Offsets , StorageLayout ,
11
+ BytecodeObject , CompactBytecode , CompactContractBytecode , CompactContractBytecodeCow ,
12
+ CompactDeployedBytecode , ConfigurableContractArtifact , ContractBytecodeSome , Offsets ,
13
+ StorageLayout ,
13
14
} ,
14
15
utils:: canonicalized,
15
16
} ;
@@ -101,6 +102,58 @@ impl ContractData {
101
102
}
102
103
}
103
104
105
+ /// Builder for creating a `ContractsByArtifact` instance, optionally including storage layouts
106
+ /// from project compile output.
107
+ pub struct ContractsByArtifactBuilder < ' a > {
108
+ /// All compiled artifact bytecodes (borrowed).
109
+ artifacts : BTreeMap < ArtifactId , CompactContractBytecodeCow < ' a > > ,
110
+ /// Optionally collected storage layouts for matching artifact IDs.
111
+ storage_layouts : BTreeMap < ArtifactId , StorageLayout > ,
112
+ }
113
+
114
+ impl < ' a > ContractsByArtifactBuilder < ' a > {
115
+ /// Creates a new builder from artifacts with present bytecode iterator.
116
+ pub fn new (
117
+ artifacts : impl IntoIterator < Item = ( ArtifactId , CompactContractBytecodeCow < ' a > ) > ,
118
+ ) -> Self {
119
+ Self { artifacts : artifacts. into_iter ( ) . collect ( ) , storage_layouts : BTreeMap :: new ( ) }
120
+ }
121
+
122
+ /// Adds storage layouts from `ProjectCompileOutput` to known artifacts.
123
+ pub fn with_storage_layouts ( mut self , output : ProjectCompileOutput ) -> Self {
124
+ self . storage_layouts = output
125
+ . into_artifacts ( )
126
+ . filter_map ( |( id, artifact) | artifact. storage_layout . map ( |layout| ( id, layout) ) )
127
+ . collect ( ) ;
128
+ self
129
+ }
130
+
131
+ /// Builds `ContractsByArtifact`.
132
+ pub fn build ( self ) -> ContractsByArtifact {
133
+ let map = self
134
+ . artifacts
135
+ . into_iter ( )
136
+ . filter_map ( |( id, artifact) | {
137
+ let name = id. name . clone ( ) ;
138
+ let CompactContractBytecodeCow { abi, bytecode, deployed_bytecode } = artifact;
139
+
140
+ Some ( (
141
+ id. clone ( ) ,
142
+ ContractData {
143
+ name,
144
+ abi : abi?. into_owned ( ) ,
145
+ bytecode : bytecode. map ( |b| b. into_owned ( ) . into ( ) ) ,
146
+ deployed_bytecode : deployed_bytecode. map ( |b| b. into_owned ( ) . into ( ) ) ,
147
+ storage_layout : self . storage_layouts . get ( & id) . map ( |l| Arc :: new ( l. clone ( ) ) ) ,
148
+ } ,
149
+ ) )
150
+ } )
151
+ . collect ( ) ;
152
+
153
+ ContractsByArtifact ( Arc :: new ( map) )
154
+ }
155
+ }
156
+
104
157
type ArtifactWithContractRef < ' a > = ( & ' a ArtifactId , & ' a ContractData ) ;
105
158
106
159
/// Wrapper type that maps an artifact to a contract ABI and bytecode.
@@ -130,28 +183,6 @@ impl ContractsByArtifact {
130
183
Self ( Arc :: new ( map) )
131
184
}
132
185
133
- /// Creates a new instance from project compile output, preserving storage layouts.
134
- pub fn with_storage_layout ( output : ProjectCompileOutput ) -> Self {
135
- let map = output
136
- . into_artifacts ( )
137
- . filter_map ( |( id, artifact) | {
138
- let name = id. name . clone ( ) ;
139
- let abi = artifact. abi ?;
140
- Some ( (
141
- id,
142
- ContractData {
143
- name,
144
- abi,
145
- bytecode : artifact. bytecode . map ( Into :: into) ,
146
- deployed_bytecode : artifact. deployed_bytecode . map ( Into :: into) ,
147
- storage_layout : artifact. storage_layout . map ( Arc :: new) ,
148
- } ,
149
- ) )
150
- } )
151
- . collect ( ) ;
152
- Self ( Arc :: new ( map) )
153
- }
154
-
155
186
/// Clears all contracts.
156
187
pub fn clear ( & mut self ) {
157
188
* self = Self :: default ( ) ;
0 commit comments