foundry_compilers/compile/output/
sources.rs1use crate::SourceFile;
2use foundry_compilers_core::utils::strip_prefix_owned;
3use semver::Version;
4use serde::{Deserialize, Serialize};
5use std::{
6 collections::BTreeMap,
7 path::{Path, PathBuf},
8};
9
10#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(transparent)]
13pub struct VersionedSourceFiles(pub BTreeMap<PathBuf, Vec<VersionedSourceFile>>);
14
15impl VersionedSourceFiles {
16 #[allow(clippy::missing_const_for_fn)]
18 pub fn slash_paths(&mut self) {
19 #[cfg(windows)]
20 {
21 use path_slash::PathExt;
22 self.0 = std::mem::take(&mut self.0)
23 .into_iter()
24 .map(|(path, files)| (PathBuf::from(path.to_slash_lossy().as_ref()), files))
25 .collect()
26 }
27 }
28
29 pub fn is_empty(&self) -> bool {
30 self.0.is_empty()
31 }
32
33 pub fn len(&self) -> usize {
34 self.0.len()
35 }
36
37 pub fn files(&self) -> impl Iterator<Item = &PathBuf> {
39 self.0.keys()
40 }
41
42 pub fn into_ids(self) -> impl Iterator<Item = (u32, PathBuf)> {
44 self.into_sources().map(|(path, source)| (source.id, path))
45 }
46
47 pub fn into_paths(self) -> impl Iterator<Item = (PathBuf, u32)> {
49 self.into_ids().map(|(id, path)| (path, id))
50 }
51
52 pub fn into_ids_with_version(self) -> impl Iterator<Item = (u32, PathBuf, Version)> {
54 self.into_sources_with_version().map(|(path, source, version)| (source.id, path, version))
55 }
56
57 pub fn find_file(&self, path: &Path) -> Option<&SourceFile> {
69 self.sources().find(|&(p, _)| p == path).map(|(_, sf)| sf)
70 }
71
72 pub fn find_file_and_version(&self, path: &Path, version: &Version) -> Option<&SourceFile> {
74 self.0.get(path).and_then(|contracts| {
75 contracts
76 .iter()
77 .find_map(|source| (source.version == *version).then_some(&source.source_file))
78 })
79 }
80
81 pub fn find_id(&self, id: u32) -> Option<&SourceFile> {
93 self.sources().filter(|(_, source)| source.id == id).map(|(_, source)| source).next()
94 }
95
96 pub fn find_id_and_version(&self, id: u32, version: &Version) -> Option<&SourceFile> {
98 self.sources_with_version()
99 .filter(|(_, source, v)| source.id == id && *v == version)
100 .map(|(_, source, _)| source)
101 .next()
102 }
103
104 pub fn remove_by_path(&mut self, path: &Path) -> Option<SourceFile> {
116 self.0.get_mut(path).and_then(|all_sources| {
117 (!all_sources.is_empty()).then(|| all_sources.remove(0).source_file)
118 })
119 }
120
121 pub fn remove_by_id(&mut self, id: u32) -> Option<SourceFile> {
133 self.0
134 .values_mut()
135 .filter_map(|sources| {
136 sources
137 .iter()
138 .position(|source| source.source_file.id == id)
139 .map(|pos| sources.remove(pos).source_file)
140 })
141 .next()
142 }
143
144 pub fn sources(&self) -> impl Iterator<Item = (&PathBuf, &SourceFile)> {
146 self.0.iter().flat_map(|(path, sources)| {
147 sources.iter().map(move |source| (path, &source.source_file))
148 })
149 }
150
151 pub fn sources_with_version(&self) -> impl Iterator<Item = (&PathBuf, &SourceFile, &Version)> {
153 self.0.iter().flat_map(|(file, sources)| {
154 sources.iter().map(move |c| (file, &c.source_file, &c.version))
155 })
156 }
157
158 pub fn into_sources(self) -> impl Iterator<Item = (PathBuf, SourceFile)> {
160 self.0.into_iter().flat_map(|(path, sources)| {
161 sources.into_iter().map(move |source| (path.clone(), source.source_file))
162 })
163 }
164
165 pub fn into_sources_with_version(self) -> impl Iterator<Item = (PathBuf, SourceFile, Version)> {
167 self.0.into_iter().flat_map(|(path, sources)| {
168 sources
169 .into_iter()
170 .map(move |source| (path.clone(), source.source_file, source.version))
171 })
172 }
173
174 pub fn join_all(&mut self, root: &Path) -> &mut Self {
176 self.0 = std::mem::take(&mut self.0)
177 .into_iter()
178 .map(|(file_path, sources)| (root.join(file_path), sources))
179 .collect();
180 self
181 }
182
183 pub fn strip_prefix_all(&mut self, base: &Path) -> &mut Self {
185 self.0 = std::mem::take(&mut self.0)
186 .into_iter()
187 .map(|(file, sources)| (strip_prefix_owned(file, base), sources))
188 .collect();
189 self
190 }
191}
192
193impl AsRef<BTreeMap<PathBuf, Vec<VersionedSourceFile>>> for VersionedSourceFiles {
194 fn as_ref(&self) -> &BTreeMap<PathBuf, Vec<VersionedSourceFile>> {
195 &self.0
196 }
197}
198
199impl AsMut<BTreeMap<PathBuf, Vec<VersionedSourceFile>>> for VersionedSourceFiles {
200 fn as_mut(&mut self) -> &mut BTreeMap<PathBuf, Vec<VersionedSourceFile>> {
201 &mut self.0
202 }
203}
204
205impl IntoIterator for VersionedSourceFiles {
206 type Item = (PathBuf, Vec<VersionedSourceFile>);
207 type IntoIter = std::collections::btree_map::IntoIter<PathBuf, Vec<VersionedSourceFile>>;
208
209 fn into_iter(self) -> Self::IntoIter {
210 self.0.into_iter()
211 }
212}
213
214#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
216pub struct VersionedSourceFile {
217 pub source_file: SourceFile,
218 pub version: Version,
219 pub build_id: String,
220 pub profile: String,
221}