Skip to content

Commit 3310af9

Browse files
committed
Add as_path() method on FilePath
1 parent 014e8be commit 3310af9

8 files changed

Lines changed: 28 additions & 28 deletions

File tree

crates/aether_path/src/file_path.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ impl FilePath {
8989
}
9090
}
9191

92+
/// Borrow the filesystem path for the `File` arm. `None` for `Virtual`.
93+
pub fn as_path(&self) -> Option<&Utf8Path> {
94+
self.as_file().map(AbsPathBuf::as_path)
95+
}
96+
9297
/// Borrow the inner [`VirtualUri`] for the `Virtual` arm.
9398
pub fn as_virtual(&self) -> Option<&VirtualUri> {
9499
match self {
@@ -102,8 +107,7 @@ impl std::fmt::Display for FilePath {
102107
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103108
// `File` arms format as a `file:` URL so the output matches
104109
// what we'd send on the wire, not as a bare path. The path
105-
// form is reachable via `as_file().map(|p| p.as_path())` for
106-
// callers that want it.
110+
// form is reachable via `as_path()` for callers that want it.
107111
match self {
108112
Self::File(p) => p.to_url().fmt(f),
109113
Self::Virtual(u) => u.fmt(f),

crates/ark/src/dap/dap_state.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl BreakpointMap {
316316
/// Returns `None` for non-`file:` URLs (`ark://`, `untitled:`, ...), when
317317
/// the file isn't on disk, and (rare) when the canonical path isn't UTF-8.
318318
fn canonical_path(path: &FilePath) -> Option<Utf8PathBuf> {
319-
let canonical = std::fs::canonicalize(path.as_file()?.as_path()).ok()?;
319+
let canonical = std::fs::canonicalize(path.as_path()?).ok()?;
320320
Utf8PathBuf::from_path_buf(canonical).ok()
321321
}
322322

@@ -1136,7 +1136,7 @@ mod tests {
11361136

11371137
// Rebuilding the path from the key would hand the frontend different
11381138
// bytes, since the key dropped the `..`.
1139-
assert_ne!(path.as_file().unwrap().as_path().as_str(), sent);
1139+
assert_ne!(path.as_path().unwrap().as_str(), sent);
11401140
}
11411141

11421142
#[test]

crates/oak_db/src/file.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,12 @@ impl File {
172172
/// [`File::root`] (for files without a registered package).
173173
fn root_by_path(db: &dyn Db, path: &FilePath) -> Option<Root> {
174174
// Virtual documents (e.g. untitled scheme) don't have roots
175-
let path = path.as_file()?.as_path();
175+
let path = path.as_path()?;
176176
db.workspace_roots()
177177
.roots(db)
178178
.iter()
179179
.filter_map(|root| {
180-
let root_path = root.path(db).as_file()?.as_path();
180+
let root_path = root.path(db).as_path()?;
181181
path.starts_with(root_path).then_some((root_path, *root))
182182
})
183183
.max_by_key(|(root_path, _)| root_path.components().count())

crates/oak_db/src/imports.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ fn anchor_dir(db: &dyn Db, calling_file: File) -> Option<Utf8PathBuf> {
8585
.filter(|r| r.kind(db) == RootKind::Workspace)
8686
{
8787
// Workspace roots are file URLs by construction.
88-
return root.path(db).as_file().map(|f| f.as_path().to_path_buf());
88+
return root.path(db).as_path().map(Utf8Path::to_path_buf);
8989
}
9090

91-
let parent = calling_file.path(db).as_file()?.as_path().parent()?;
91+
let parent = calling_file.path(db).as_path()?.parent()?;
9292
Some(parent.to_path_buf())
9393
}
9494

crates/oak_scan/src/scheduler.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use std::collections::HashSet;
5555
use std::path::PathBuf;
5656

5757
use aether_path::FilePath;
58+
use camino::Utf8Path;
5859
use camino::Utf8PathBuf;
5960
use oak_db::Db;
6061
use oak_db::DbInputs;
@@ -191,7 +192,7 @@ impl ScanScheduler {
191192
.iter()
192193
.filter_map(|path| {
193194
let path = FilePath::from_path_buf(path.clone())?;
194-
let scan_path = path.as_file()?.as_path().to_path_buf();
195+
let scan_path = path.as_path()?.to_path_buf();
195196
Some((scan_path, path))
196197
})
197198
.collect();
@@ -264,7 +265,7 @@ impl ScanScheduler {
264265
// instead of applying surgically against a transient world.
265266
let mut description_roots: HashSet<Root> = HashSet::new();
266267
for event in &events {
267-
let Some(path) = event.path.as_file().map(|f| f.as_path().to_path_buf()) else {
268+
let Some(path) = event.path.as_path().map(Utf8Path::to_path_buf) else {
268269
continue;
269270
};
270271
if path.file_name().is_some_and(|name| name == "DESCRIPTION") {
@@ -285,7 +286,7 @@ impl ScanScheduler {
285286

286287
// Pass 2: R-file events.
287288
for event in events {
288-
let Some(path) = event.path.as_file().map(|f| f.as_path().to_path_buf()) else {
289+
let Some(path) = event.path.as_path().map(Utf8Path::to_path_buf) else {
289290
continue;
290291
};
291292
if path.file_name().is_some_and(|name| name == "DESCRIPTION") {
@@ -364,7 +365,7 @@ impl ScanScheduler {
364365
// would stay pending forever. On success the buffer rides along
365366
// and replays when the requeued scan finishes. On failure we
366367
// fall back to the idle drain.
367-
let scan_path = root.path(db).as_file().map(|f| f.as_path().to_path_buf());
368+
let scan_path = root.path(db).as_path().map(Utf8Path::to_path_buf);
368369
match scan_path {
369370
Some(path) => {
370371
self.state.insert(root, ScanState::Scanning);
@@ -417,11 +418,11 @@ impl ScanScheduler {
417418
},
418419
Some(ScanState::ScanningWithRescanQueued) => None,
419420
None => {
420-
let Some(abs) = root.path(db).as_file() else {
421+
let Some(path) = root.path(db).as_path() else {
421422
log::warn!("Skipping rescan: root path is not a filesystem path");
422423
return None;
423424
};
424-
let path = abs.as_path().to_path_buf();
425+
let path = path.to_path_buf();
425426
self.state.insert(root, ScanState::Scanning);
426427
Some(ScanRequest { root, path })
427428
},
@@ -455,11 +456,11 @@ fn workspace_root_paths<DB: Db + DbInputs>(db: &DB) -> Vec<(Utf8PathBuf, Root)>
455456
.roots(db)
456457
.iter()
457458
.filter_map(|root| {
458-
let Some(abs) = root.path(db).as_file() else {
459+
let Some(path) = root.path(db).as_path() else {
459460
log::warn!("Skipping workspace root: path is not a filesystem path");
460461
return None;
461462
};
462-
Some((abs.as_path().to_path_buf(), *root))
463+
Some((path.to_path_buf(), *root))
463464
})
464465
.collect()
465466
}

crates/oak_scan/src/tests/scheduler.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,7 @@ fn test_set_workspace_paths_inserts_empty_root_immediately() {
266266
// `FilePath` construction is lexical, so the stored path is the one
267267
// we handed in, byte for byte.
268268
assert_eq!(
269-
roots[0]
270-
.path(&db)
271-
.as_file()
272-
.unwrap()
273-
.as_path()
274-
.as_std_path(),
269+
roots[0].path(&db).as_path().unwrap().as_std_path(),
275270
tmp.path()
276271
);
277272
}

crates/oak_scan/src/tests/watch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fn remove_watched_file(db: &mut OakDatabase, url: FilePath) {
7272
/// Sync helper: force a fresh full rescan of `root`. Equivalent to the
7373
/// production trigger of a DESCRIPTION watcher event hitting the root.
7474
fn rescan_workspace_root(db: &mut OakDatabase, root: Root) {
75-
let path = root.path(db).as_file().unwrap().as_path().to_path_buf();
75+
let path = root.path(db).as_path().unwrap().to_path_buf();
7676
let result = ScanRequest { root, path }.run();
7777
let mut scheduler = ScanScheduler::new();
7878
let reqs = scheduler.apply_scan_completed(db, result, &HashSet::new());

crates/oak_scan/src/watch.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ pub(crate) fn add_watched_file<DB: Db + DbInputs>(db: &mut DB, path: FilePath, c
5656
return;
5757
}
5858

59-
let Some(abs) = path.as_file() else {
59+
let Some(fs_path) = path.as_path() else {
6060
log::warn!("Skipping add_watched_file: URL is not a file path");
6161
return;
6262
};
6363

64-
let Some(placement) = classify(db, abs.as_path()) else {
64+
let Some(placement) = classify(db, fs_path) else {
6565
// Either the URL falls outside every workspace, or it lives
6666
// inside a package subdir we don't track (tests/, inst/, ...).
6767
return;
@@ -147,7 +147,7 @@ fn classify<DB: Db + DbInputs>(db: &DB, path: &Utf8Path) -> Option<Placement> {
147147
}
148148

149149
let root = workspace_root_containing(db, path)?;
150-
let root_path = root.path(db).as_file()?.as_path();
150+
let root_path = root.path(db).as_path()?;
151151

152152
// Find the nearest ancestor (within `root_path`) that contains a
153153
// `DESCRIPTION`. None means no package above the file, so it's a
@@ -180,8 +180,8 @@ fn workspace_root_containing<DB: Db + DbInputs>(db: &DB, path: &Utf8Path) -> Opt
180180
db.workspace_roots()
181181
.roots(db)
182182
.iter()
183-
.find(|root| match root.path(db).as_file() {
184-
Some(root_path) => path.starts_with(root_path.as_path()),
183+
.find(|root| match root.path(db).as_path() {
184+
Some(root_path) => path.starts_with(root_path),
185185
None => false,
186186
})
187187
.copied()

0 commit comments

Comments
 (0)