Skip to main content

turbo_tasks_fs/
util.rs

1use std::{
2    io::{self, ErrorKind},
3    path::Path,
4};
5
6use anyhow::{Context, Result, anyhow};
7use turbo_tasks::ResolvedVc;
8use url::Url;
9
10use crate::{DiskFileSystem, FileSystemPath};
11
12/// Converts a disk access `Result<T>` into a `Result<Some<T>>`, where a [`ErrorKind::NotFound`] (or
13/// [`ErrorKind::InvalidFilename`]) error results in a [`None`] value. This is purely to reduce
14/// boilerplate code comparing [`ErrorKind::NotFound`] errors against all other errors.
15pub fn extract_disk_access<T>(value: io::Result<T>, path: &Path) -> Result<Option<T>> {
16    match value {
17        Ok(v) => Ok(Some(v)),
18        Err(e) if matches!(e.kind(), ErrorKind::NotFound | ErrorKind::InvalidFilename) => Ok(None),
19        // ast-grep-ignore: no-context-format
20        Err(e) => Err(anyhow!(e).context(format!("reading file {}", path.display()))),
21    }
22}
23
24pub async fn uri_from_file(root: FileSystemPath, path: Option<&str>) -> Result<String> {
25    let root_fs = root.fs;
26    let root_fs = &*ResolvedVc::try_downcast_type::<DiskFileSystem>(root_fs)
27        .context("Expected root to have a DiskFileSystem")?
28        .await?;
29
30    let path = match path {
31        Some(path) => root.join(path)?,
32        None => root,
33    };
34
35    // `to_sys_path` returns a win32 path on Windows. `Url::from_file_path` can also handle
36    // verbatim (`\\?\`-prefixed) disk and UNC paths, in case that conversion failed.
37    let sys_path = root_fs.to_sys_path(&path);
38    Ok(String::from(Url::from_file_path(&sys_path).map_err(
39        |_| anyhow!("path {sys_path:?} cannot be converted to a file:// URI"),
40    )?))
41}