revive_solc_json_interface/standard_json/input/settings/selection/file/
mod.rs

1//! The `solc --standard-json` output file selection.
2
3pub mod flag;
4
5use std::collections::HashSet;
6
7use serde::Deserialize;
8use serde::Serialize;
9
10use self::flag::Flag as SelectionFlag;
11
12/// The `solc --standard-json` output file selection.
13#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
14pub struct File {
15    /// The per-file output selections.
16    #[serde(default, rename = "", skip_serializing_if = "HashSet::is_empty")]
17    pub per_file: HashSet<SelectionFlag>,
18    /// The per-contract output selections.
19    #[serde(default, rename = "*", skip_serializing_if = "HashSet::is_empty")]
20    pub per_contract: HashSet<SelectionFlag>,
21}
22
23impl File {
24    /// A shortcut constructor.
25    pub fn new(flags: Vec<SelectionFlag>) -> Self {
26        let mut per_file = HashSet::new();
27        let mut per_contract = HashSet::new();
28        for flag in flags.into_iter() {
29            match flag {
30                SelectionFlag::AST => {
31                    per_file.insert(SelectionFlag::AST);
32                }
33                flag => {
34                    per_contract.insert(flag);
35                }
36            }
37        }
38        Self {
39            per_file,
40            per_contract,
41        }
42    }
43
44    /// Creates the selection required for test compilation (includes EVM bytecode).
45    pub fn new_required_for_tests() -> Self {
46        Self {
47            per_file: HashSet::from_iter([SelectionFlag::AST]),
48            per_contract: HashSet::from_iter([
49                SelectionFlag::EVMBC,
50                SelectionFlag::EVMDBC,
51                SelectionFlag::MethodIdentifiers,
52                SelectionFlag::Metadata,
53                SelectionFlag::Yul,
54            ]),
55        }
56    }
57
58    /// Extends the output selection with another one.
59    pub fn extend(&mut self, other: Self) -> &mut Self {
60        self.per_file.extend(other.per_file);
61        self.per_contract.extend(other.per_contract);
62        self
63    }
64
65    /// Returns flags that are going to be automatically added by the compiler,
66    /// but were not explicitly requested by the user.
67    ///
68    /// Afterwards, the flags are used to prune JSON output before returning it.
69    pub fn selection_to_prune(&self) -> Self {
70        let required_per_file = vec![SelectionFlag::AST];
71        let required_per_contract = vec![
72            SelectionFlag::MethodIdentifiers,
73            SelectionFlag::Metadata,
74            SelectionFlag::Yul,
75        ];
76
77        let mut unset_per_file = HashSet::with_capacity(required_per_file.len());
78        let mut unset_per_contract = HashSet::with_capacity(required_per_contract.len());
79
80        for flag in required_per_file {
81            if !self.per_file.contains(&flag) {
82                unset_per_file.insert(flag);
83            }
84        }
85        for flag in required_per_contract {
86            if !self.per_contract.contains(&flag) {
87                unset_per_contract.insert(flag);
88            }
89        }
90        Self {
91            per_file: unset_per_file,
92            per_contract: unset_per_contract,
93        }
94    }
95    /// Whether the flag is requested.
96    pub fn contains(&self, flag: &SelectionFlag) -> bool {
97        match flag {
98            flag @ SelectionFlag::AST => self.per_file.contains(flag),
99            flag => self.per_contract.contains(flag),
100        }
101    }
102
103    /// Checks whether the selection is empty.
104    pub fn is_empty(&self) -> bool {
105        self.per_file.is_empty() && self.per_contract.is_empty()
106    }
107}