revive_solc_json_interface/combined_json/
mod.rs

1//! The `solc --combined-json` output.
2
3use std::collections::BTreeMap;
4
5use serde::Deserialize;
6use serde::Serialize;
7
8use self::contract::Contract;
9
10pub mod contract;
11pub mod selector;
12
13/// The `solc --combined-json` output.
14#[derive(Debug, Serialize, Deserialize)]
15pub struct CombinedJson {
16    /// The contract entries.
17    pub contracts: BTreeMap<String, Contract>,
18    /// The list of source files.
19    #[serde(default, rename = "sourceList", skip_serializing_if = "Vec::is_empty")]
20    pub source_list: Vec<String>,
21    /// The source code extra data, including the AST.
22    #[serde(default, skip_serializing_if = "serde_json::Value::is_null")]
23    pub sources: serde_json::Value,
24    /// The `solc` compiler version.
25    pub version: String,
26    /// The `resolc` compiler version.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    #[cfg(feature = "resolc")]
29    pub resolc_version: Option<String>,
30}
31
32#[cfg(feature = "resolc")]
33impl CombinedJson {
34    /// A shortcut constructor.
35    pub fn new(solc_version: semver::Version, resolc_version: Option<String>) -> Self {
36        Self {
37            contracts: BTreeMap::new(),
38            source_list: Vec::new(),
39            sources: serde_json::Value::Null,
40            version: solc_version.to_string(),
41            resolc_version,
42        }
43    }
44
45    /// Writes the JSON to the specified directory.
46    pub fn write_to_directory(
47        self,
48        output_directory: &std::path::Path,
49        overwrite: bool,
50    ) -> anyhow::Result<()> {
51        let mut file_path = output_directory.to_owned();
52        file_path.push(format!("combined.{}", revive_common::EXTENSION_JSON));
53
54        if file_path.exists() && !overwrite {
55            anyhow::bail!(
56                "Refusing to overwrite an existing file {file_path:?} (use --overwrite to force)."
57            );
58        }
59
60        std::fs::write(
61            file_path.as_path(),
62            serde_json::to_vec(&self).expect("Always valid").as_slice(),
63        )
64        .map_err(|error| anyhow::anyhow!("File {file_path:?} writing: {error}"))?;
65
66        Ok(())
67    }
68}