Skip to content

Commit bbaff8b

Browse files
author
Paolo Tranquilli
committed
Rust: cleanup workspace aggregation
1 parent 3c06428 commit bbaff8b

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

rust/extractor/src/rust_analyzer.rs

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use itertools::Itertools;
2-
use log::{debug, error, info};
2+
use log::{debug, error, info, warn};
33
use ra_ap_base_db::SourceDatabase;
44
use ra_ap_hir::Semantics;
55
use ra_ap_ide_db::RootDatabase;
@@ -16,6 +16,7 @@ use ra_ap_syntax::SyntaxError;
1616
use ra_ap_vfs::Vfs;
1717
use ra_ap_vfs::VfsPath;
1818
use ra_ap_vfs::{AbsPathBuf, FileId};
19+
use serde::Deserialize;
1920
use std::borrow::Cow;
2021
use std::collections::{HashMap, HashSet};
2122
use std::fs;
@@ -131,8 +132,19 @@ impl<'a> RustAnalyzer<'a> {
131132
}
132133
}
133134

135+
#[derive(Deserialize)]
136+
struct CargoManifestMembersSlice {
137+
#[serde(default)]
138+
members: Vec<String>,
139+
}
140+
141+
#[derive(Deserialize)]
142+
struct CargoManifestSlice {
143+
workspace: Option<CargoManifestMembersSlice>,
144+
}
145+
134146
struct ToMlReader {
135-
cache: HashMap<ManifestPath, Rc<toml::Table>>,
147+
cache: HashMap<ManifestPath, Rc<CargoManifestSlice>>,
136148
}
137149

138150
impl ToMlReader {
@@ -142,15 +154,15 @@ impl ToMlReader {
142154
}
143155
}
144156

145-
fn read(&mut self, manifest: &ManifestPath) -> anyhow::Result<Rc<toml::Table>> {
157+
fn read(&mut self, manifest: &ManifestPath) -> anyhow::Result<Rc<CargoManifestSlice>> {
146158
if let Some(table) = self.cache.get(manifest) {
147159
return Ok(table.clone());
148160
}
149161
let content = fs::read_to_string(manifest).map_err(|e| {
150162
error!("failed to read {} ({e})", manifest.as_str());
151163
e
152164
})?;
153-
let table = Rc::<toml::Table>::new(content.parse().map_err(|e| {
165+
let table = Rc::<CargoManifestSlice>::new(toml::from_str(&content).map_err(|e| {
154166
error!("failed to parse {} ({e})", manifest.as_str());
155167
e
156168
})?);
@@ -159,46 +171,50 @@ impl ToMlReader {
159171
}
160172
}
161173

162-
fn find_workspace(
163-
reader: &mut ToMlReader,
164-
manifest: &ProjectManifest,
165-
) -> anyhow::Result<ProjectManifest> {
174+
fn find_workspace(reader: &mut ToMlReader, manifest: &ProjectManifest) -> Option<ProjectManifest> {
166175
let ProjectManifest::CargoToml(cargo) = manifest else {
167-
return Err(anyhow::anyhow!("{manifest} not a cargo manifest"));
176+
return None;
168177
};
169-
let toml = reader.read(cargo)?;
170-
if toml.contains_key("workspace") {
171-
return Ok(manifest.clone());
178+
let parsed_cargo = reader.read(cargo).ok()?;
179+
if parsed_cargo.workspace.is_some() {
180+
debug!("{cargo} is a workspace");
181+
return Some(manifest.clone());
172182
}
173183
let Some(parent_dir) = cargo.parent().parent() else {
174-
return Err(anyhow::anyhow!("no parent dir for {cargo}"));
184+
warn!("no parent dir for {cargo}");
185+
return None;
175186
};
176-
let discovered = ProjectManifest::discover(parent_dir)?;
187+
let discovered = ProjectManifest::discover(parent_dir)
188+
.map_err(|e| {
189+
error!(
190+
"encountered error while searching for manifests under {}: {e}",
191+
parent_dir.as_str()
192+
);
193+
e
194+
})
195+
.ok()?;
177196
discovered
178197
.iter()
179-
.filter_map(|it| match it {
198+
.find_map(|it| match it {
180199
ProjectManifest::CargoToml(other)
181200
if cargo.starts_with(other.parent())
182201
&& reader.read(other).is_ok_and(|it| {
183-
it.get("workspace")
184-
.and_then(|w| w.as_table())
185-
.and_then(|t| t.get("members"))
186-
.and_then(|ms| ms.as_array())
187-
.is_some_and(|ms| {
188-
ms.iter().any(|m| {
189-
m.as_str()
190-
.is_some_and(|s| other.parent().join(s) == cargo.parent())
191-
})
192-
})
202+
it.workspace.as_ref().is_some_and(|w| {
203+
w.members
204+
.iter()
205+
.any(|m| other.parent().join(m) == cargo.parent())
206+
})
193207
}) =>
194208
{
195209
debug!("found workspace {other} containing {cargo}");
196210
Some(it.clone())
197211
}
198212
_ => None,
199213
})
200-
.next()
201-
.ok_or(anyhow::anyhow!("no workspace found for {manifest}"))
214+
.or_else(|| {
215+
debug!("no workspace found for {cargo}");
216+
None
217+
})
202218
}
203219

204220
pub fn find_project_manifests(

0 commit comments

Comments
 (0)