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 pub fn slash_paths(&mut self) {
18 #[cfg(windows)]
19 {
20 use path_slash::PathExt;
21 self.0 = std::mem::take(&mut self.0)
22 .into_iter()
23 .map(|(path, files)| (PathBuf::from(path.to_slash_lossy().as_ref()), files))
24 .collect()
25 }
26 }
27
28 pub fn is_empty(&self) -> bool {
29 self.0.is_empty()
30 }
31
32 pub fn len(&self) -> usize {
33 self.0.len()
34 }
35
36 pub fn files(&self) -> impl Iterator<Item = &PathBuf> {
38 self.0.keys()
39 }
40
41 pub fn into_ids(self) -> impl Iterator<Item = (u32, PathBuf)> {
43 self.into_sources().map(|(path, source)| (source.id, path))
44 }
45
46 pub fn into_paths(self) -> impl Iterator<Item = (PathBuf, u32)> {
48 self.into_ids().map(|(id, path)| (path, id))
49 }
50
51 pub fn into_ids_with_version(self) -> impl Iterator<Item = (u32, PathBuf, Version)> {
53 self.into_sources_with_version().map(|(path, source, version)| (source.id, path, version))
54 }
55
56 pub fn find_file(&self, path: &Path) -> Option<&SourceFile> {
68 self.sources().find(|&(p, _)| p == path).map(|(_, sf)| sf)
69 }
70
71 pub fn find_file_and_version(&self, path: &Path, version: &Version) -> Option<&SourceFile> {
73 self.0.get(path).and_then(|contracts| {
74 contracts.iter().find_map(|source| {
75 if source.version == *version {
76 Some(&source.source_file)
77 } else {
78 None
79 }
80 })
81 })
82 }
83
84 pub fn find_id(&self, id: u32) -> Option<&SourceFile> {
96 self.sources().filter(|(_, source)| source.id == id).map(|(_, source)| source).next()
97 }
98
99 pub fn find_id_and_version(&self, id: u32, version: &Version) -> Option<&SourceFile> {
101 self.sources_with_version()
102 .filter(|(_, source, v)| source.id == id && *v == version)
103 .map(|(_, source, _)| source)
104 .next()
105 }
106
107 pub fn remove_by_path(&mut self, path: &Path) -> Option<SourceFile> {
119 self.0.get_mut(path).and_then(|all_sources| {
120 if !all_sources.is_empty() {
121 Some(all_sources.remove(0).source_file)
122 } else {
123 None
124 }
125 })
126 }
127
128 pub fn remove_by_id(&mut self, id: u32) -> Option<SourceFile> {
140 self.0
141 .values_mut()
142 .filter_map(|sources| {
143 sources
144 .iter()
145 .position(|source| source.source_file.id == id)
146 .map(|pos| sources.remove(pos).source_file)
147 })
148 .next()
149 }
150
151 pub fn sources(&self) -> impl Iterator<Item = (&PathBuf, &SourceFile)> {
153 self.0.iter().flat_map(|(path, sources)| {
154 sources.iter().map(move |source| (path, &source.source_file))
155 })
156 }
157
158 pub fn sources_with_version(&self) -> impl Iterator<Item = (&PathBuf, &SourceFile, &Version)> {
160 self.0.iter().flat_map(|(file, sources)| {
161 sources.iter().map(move |c| (file, &c.source_file, &c.version))
162 })
163 }
164
165 pub fn into_sources(self) -> impl Iterator<Item = (PathBuf, SourceFile)> {
167 self.0.into_iter().flat_map(|(path, sources)| {
168 sources.into_iter().map(move |source| (path.clone(), source.source_file))
169 })
170 }
171
172 pub fn into_sources_with_version(self) -> impl Iterator<Item = (PathBuf, SourceFile, Version)> {
174 self.0.into_iter().flat_map(|(path, sources)| {
175 sources
176 .into_iter()
177 .map(move |source| (path.clone(), source.source_file, source.version))
178 })
179 }
180
181 pub fn join_all(&mut self, root: &Path) -> &mut Self {
183 self.0 = std::mem::take(&mut self.0)
184 .into_iter()
185 .map(|(file_path, sources)| (root.join(file_path), sources))
186 .collect();
187 self
188 }
189
190 pub fn strip_prefix_all(&mut self, base: &Path) -> &mut Self {
192 self.0 = std::mem::take(&mut self.0)
193 .into_iter()
194 .map(|(file, sources)| (strip_prefix_owned(file, base), sources))
195 .collect();
196 self
197 }
198}
199
200impl AsRef<BTreeMap<PathBuf, Vec<VersionedSourceFile>>> for VersionedSourceFiles {
201 fn as_ref(&self) -> &BTreeMap<PathBuf, Vec<VersionedSourceFile>> {
202 &self.0
203 }
204}
205
206impl AsMut<BTreeMap<PathBuf, Vec<VersionedSourceFile>>> for VersionedSourceFiles {
207 fn as_mut(&mut self) -> &mut BTreeMap<PathBuf, Vec<VersionedSourceFile>> {
208 &mut self.0
209 }
210}
211
212impl IntoIterator for VersionedSourceFiles {
213 type Item = (PathBuf, Vec<VersionedSourceFile>);
214 type IntoIter = std::collections::btree_map::IntoIter<PathBuf, Vec<VersionedSourceFile>>;
215
216 fn into_iter(self) -> Self::IntoIter {
217 self.0.into_iter()
218 }
219}
220
221#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
223pub struct VersionedSourceFile {
224 pub source_file: SourceFile,
225 pub version: Version,
226 pub build_id: String,
227 pub profile: String,
228}