//! The `solc --standard-json` input. pub mod language; pub mod settings; pub mod source; use std::collections::BTreeMap; use std::collections::BTreeSet; use std::path::PathBuf; #[cfg(all(feature = "parallel", feature = "resolc"))] use rayon::iter::{IntoParallelIterator, ParallelIterator}; use serde::Deserialize; use serde::Serialize; use crate::standard_json::input::settings::metadata::Metadata as SolcStandardJsonInputSettingsMetadata; use crate::standard_json::input::settings::optimizer::Optimizer as SolcStandardJsonInputSettingsOptimizer; use crate::standard_json::input::settings::selection::Selection as SolcStandardJsonInputSettingsSelection; #[cfg(feature = "resolc")] use crate::warning::Warning; use self::language::Language; use self::settings::Settings; use self::source::Source; /// The `solc --standard-json` input. #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Input { /// The input language. pub language: Language, /// The input source code files hashmap. pub sources: BTreeMap, /// The compiler settings. pub settings: Settings, /// The suppressed warnings. #[cfg(feature = "resolc")] #[serde(skip_serializing)] pub suppressed_warnings: Option>, } impl Input { /// A shortcut constructor from stdin. pub fn try_from_stdin() -> anyhow::Result { let mut input: Self = serde_json::from_reader(std::io::BufReader::new(std::io::stdin()))?; input .settings .output_selection .get_or_insert_with(SolcStandardJsonInputSettingsSelection::default) .extend_with_required(); Ok(input) } /// A shortcut constructor from paths. #[allow(clippy::too_many_arguments)] pub fn try_from_paths( language: Language, evm_version: Option, paths: &[PathBuf], library_map: Vec, remappings: Option>, output_selection: SolcStandardJsonInputSettingsSelection, optimizer: SolcStandardJsonInputSettingsOptimizer, metadata: Option, #[cfg(feature = "resolc")] suppressed_warnings: Option>, ) -> anyhow::Result { let mut paths: BTreeSet = paths.iter().cloned().collect(); let libraries = Settings::parse_libraries(library_map)?; for library_file in libraries.keys() { paths.insert(PathBuf::from(library_file)); } let sources = paths .iter() .map(|path| { let source = Source::try_from(path.as_path()).unwrap_or_else(|error| { panic!("Source code file {path:?} reading error: {error}") }); (path.to_string_lossy().to_string(), source) }) .collect(); Ok(Self { language, sources, settings: Settings::new( evm_version, libraries, remappings, output_selection, optimizer, metadata, ), #[cfg(feature = "resolc")] suppressed_warnings, }) } /// A shortcut constructor from source code. /// Only for the integration test purposes. #[cfg(feature = "resolc")] #[allow(clippy::too_many_arguments)] pub fn try_from_sources( evm_version: Option, sources: BTreeMap, libraries: BTreeMap>, remappings: Option>, output_selection: SolcStandardJsonInputSettingsSelection, optimizer: SolcStandardJsonInputSettingsOptimizer, metadata: Option, suppressed_warnings: Option>, ) -> anyhow::Result { #[cfg(feature = "parallel")] let iter = sources.into_par_iter(); // Parallel iterator #[cfg(not(feature = "parallel"))] let iter = sources.into_iter(); // Sequential iterator let sources = iter .map(|(path, content)| (path, Source::from(content))) .collect(); Ok(Self { language: Language::Solidity, sources, settings: Settings::new( evm_version, libraries, remappings, output_selection, optimizer, metadata, ), suppressed_warnings, }) } /// Sets the necessary defaults. pub fn normalize(&mut self, version: &semver::Version) { self.settings.normalize(version); } }