foundry_compilers_artifacts_solc/
configurable.rs

1use crate::{
2    Ast, CompactBytecode, CompactContract, CompactContractBytecode, CompactContractBytecodeCow,
3    CompactDeployedBytecode, DevDoc, Ewasm, FunctionDebugData, GasEstimates, GeneratedSource,
4    Metadata, Offsets, SourceFile, StorageLayout, UserDoc,
5};
6use alloy_json_abi::JsonAbi;
7use serde::{Deserialize, Serialize};
8use std::{borrow::Cow, collections::BTreeMap};
9
10/// Represents the `Artifact` that `ConfigurableArtifacts` emits.
11///
12/// This is essentially a superset of [`CompactContractBytecode`].
13#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct ConfigurableContractArtifact {
16    /// The Ethereum Contract ABI. If empty, it is represented as an empty
17    /// array. See <https://docs.soliditylang.org/en/develop/abi-spec.html>
18    pub abi: Option<JsonAbi>,
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub bytecode: Option<CompactBytecode>,
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub deployed_bytecode: Option<CompactDeployedBytecode>,
23    #[serde(default, skip_serializing_if = "Option::is_none")]
24    pub assembly: Option<String>,
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub legacy_assembly: Option<serde_json::Value>,
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub opcodes: Option<String>,
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub method_identifiers: Option<BTreeMap<String, String>>,
31    #[serde(default, skip_serializing_if = "Vec::is_empty")]
32    pub generated_sources: Vec<GeneratedSource>,
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub function_debug_data: Option<BTreeMap<String, FunctionDebugData>>,
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub gas_estimates: Option<GasEstimates>,
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    pub raw_metadata: Option<String>,
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub metadata: Option<Metadata>,
41    #[serde(default, skip_serializing_if = "Option::is_none")]
42    pub storage_layout: Option<StorageLayout>,
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub transient_storage_layout: Option<StorageLayout>,
45    #[serde(default, skip_serializing_if = "Option::is_none")]
46    pub userdoc: Option<UserDoc>,
47    #[serde(default, skip_serializing_if = "Option::is_none")]
48    pub devdoc: Option<DevDoc>,
49    #[serde(default, skip_serializing_if = "Option::is_none")]
50    pub ir: Option<String>,
51    #[serde(default, skip_serializing_if = "Option::is_none")]
52    pub ir_optimized: Option<String>,
53    #[serde(default, skip_serializing_if = "Option::is_none")]
54    pub ir_optimized_ast: Option<serde_json::Value>,
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub ewasm: Option<Ewasm>,
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub ast: Option<Ast>,
59    /// The identifier of the source file
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub id: Option<u32>,
62}
63
64impl ConfigurableContractArtifact {
65    /// Returns the inner element that contains the core bytecode related information
66    pub fn into_contract_bytecode(self) -> CompactContractBytecode {
67        self.into()
68    }
69
70    /// Looks for all link references in deployment and runtime bytecodes
71    pub fn all_link_references(&self) -> BTreeMap<String, BTreeMap<String, Vec<Offsets>>> {
72        let mut links = BTreeMap::new();
73        if let Some(bcode) = &self.bytecode {
74            links.extend(bcode.link_references.clone());
75        }
76
77        if let Some(d_bcode) = &self.deployed_bytecode {
78            if let Some(bcode) = &d_bcode.bytecode {
79                links.extend(bcode.link_references.clone());
80            }
81        }
82        links
83    }
84
85    /// Returns the source file of this artifact's contract
86    pub fn source_file(&self) -> Option<SourceFile> {
87        self.id.map(|id| SourceFile { id, ast: self.ast.clone() })
88    }
89}
90
91impl From<ConfigurableContractArtifact> for CompactContractBytecode {
92    fn from(artifact: ConfigurableContractArtifact) -> Self {
93        Self {
94            abi: artifact.abi,
95            bytecode: artifact.bytecode,
96            deployed_bytecode: artifact.deployed_bytecode,
97        }
98    }
99}
100
101impl From<ConfigurableContractArtifact> for CompactContract {
102    fn from(artifact: ConfigurableContractArtifact) -> Self {
103        CompactContractBytecode::from(artifact).into()
104    }
105}
106
107impl<'a> From<&'a ConfigurableContractArtifact> for CompactContractBytecodeCow<'a> {
108    fn from(artifact: &'a ConfigurableContractArtifact) -> Self {
109        CompactContractBytecodeCow {
110            abi: artifact.abi.as_ref().map(Cow::Borrowed),
111            bytecode: artifact.bytecode.as_ref().map(Cow::Borrowed),
112            deployed_bytecode: artifact.deployed_bytecode.as_ref().map(Cow::Borrowed),
113        }
114    }
115}