revive_solc_json_interface/standard_json/input/settings/selection/file/
mod.rs1pub mod flag;
4
5use std::collections::HashSet;
6
7use serde::Deserialize;
8use serde::Serialize;
9
10use self::flag::Flag as SelectionFlag;
11
12#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
14pub struct File {
15 #[serde(default, rename = "", skip_serializing_if = "HashSet::is_empty")]
17 pub per_file: HashSet<SelectionFlag>,
18 #[serde(default, rename = "*", skip_serializing_if = "HashSet::is_empty")]
21 pub per_contract: HashSet<SelectionFlag>,
22}
23
24impl File {
25 pub fn new(flags: Vec<SelectionFlag>) -> Self {
27 let mut per_file = HashSet::new();
28 let mut per_contract = HashSet::new();
29 for flag in flags.into_iter() {
30 match flag {
31 SelectionFlag::AST => {
32 per_file.insert(SelectionFlag::AST);
33 }
34 flag => {
35 per_contract.insert(flag);
36 }
37 }
38 }
39 Self {
40 per_file,
41 per_contract,
42 }
43 }
44
45 pub fn new_required_for_codegen() -> Self {
47 Self::new(SelectionFlag::codegen_requirements().into())
48 }
49
50 pub fn new_required_for_tests() -> Self {
52 Self {
53 per_file: HashSet::from_iter([SelectionFlag::AST]),
54 per_contract: HashSet::from_iter([
55 SelectionFlag::EVMBC,
56 SelectionFlag::EVMDBC,
57 SelectionFlag::MethodIdentifiers,
58 SelectionFlag::Metadata,
59 SelectionFlag::Yul,
60 ]),
61 }
62 }
63
64 pub fn extend(&mut self, other: Self) -> &mut Self {
66 self.per_file.extend(other.per_file);
67 self.per_contract.extend(other.per_contract);
68 self
69 }
70
71 pub fn selection_to_prune(&self) -> Self {
76 let unset_per_file = SelectionFlag::all()
77 .iter()
78 .copied()
79 .filter(|flag| !self.per_file.contains(flag))
80 .collect();
81
82 let requests_evm_parent = self.contains(SelectionFlag::EVM);
83 let evm_children = SelectionFlag::evm_children();
84 let requests_evm_child = self.contains_any(evm_children);
85
86 let unset_per_contract: HashSet<_> = SelectionFlag::all()
87 .iter()
88 .copied()
89 .filter(|flag| {
90 if requests_evm_parent && evm_children.contains(flag) {
92 return false;
93 }
94 if requests_evm_child && *flag == SelectionFlag::EVM {
96 return false;
97 }
98 !self.per_contract.contains(flag)
99 })
100 .collect();
101
102 Self {
103 per_file: unset_per_file,
104 per_contract: unset_per_contract,
105 }
106 }
107
108 pub fn contains(&self, flag: SelectionFlag) -> bool {
110 match flag {
111 SelectionFlag::AST => self.per_file.contains(&flag),
112 _ => self.per_contract.contains(&flag),
113 }
114 }
115
116 pub fn contains_any(&self, flags: &[SelectionFlag]) -> bool {
118 flags.iter().any(|&flag| self.contains(flag))
119 }
120
121 pub fn requests_codegen(&self) -> bool {
123 self.contains_any(&[
124 SelectionFlag::EVM,
125 SelectionFlag::EVMBC,
126 SelectionFlag::EVMDBC,
127 SelectionFlag::Assembly,
128 ])
129 }
130
131 pub fn is_empty(&self) -> bool {
133 self.per_file.is_empty() && self.per_contract.is_empty()
134 }
135}