Skip to main content

dada_compiler/
realfs.rs

1use std::path::{Path, PathBuf};
2
3use crate::VirtualFileSystem;
4use dada_util::{Fallible, anyhow, bail};
5use url::Url;
6
7pub struct RealFs {
8    base_dir: Option<PathBuf>,
9}
10
11impl Default for RealFs {
12    fn default() -> Self {
13        Self::new()
14    }
15}
16
17impl RealFs {
18    pub fn new() -> Self {
19        Self {
20            base_dir: std::env::current_dir().ok(),
21        }
22    }
23
24    fn validate_scheme(url: &Url) -> Fallible<PathBuf> {
25        if url.scheme() != "file" {
26            bail!("unsupported scheme: {}", url.scheme());
27        }
28        url.to_file_path()
29            .map_err(|()| anyhow!("not a file path: {url}"))
30    }
31}
32
33impl VirtualFileSystem for RealFs {
34    fn contents(&self, url: &Url) -> Fallible<String> {
35        let path = Self::validate_scheme(url)?;
36        Ok(std::fs::read_to_string(&path)?)
37    }
38
39    fn exists(&self, url: &Url) -> bool {
40        match Self::validate_scheme(url) {
41            Ok(path) => path.exists(),
42            Err(_) => false,
43        }
44    }
45
46    fn path_url(&self, path: &Path) -> Fallible<Url> {
47        let path = if let Some(base_dir) = &self.base_dir {
48            base_dir.join(path)
49        } else {
50            path.to_path_buf()
51        };
52
53        Url::from_file_path(&path)
54            .map_err(|()| anyhow!("unable to construct URL from `{}`", path.display()))
55    }
56
57    fn url_display(&self, url: &Url) -> String {
58        match url.scheme() {
59            "file" => match url.to_file_path() {
60                Ok(path) => {
61                    if let Some(base_dir) = &self.base_dir
62                        && let Ok(suffix) = path.strip_prefix(base_dir)
63                    {
64                        return suffix.display().to_string();
65                    }
66                    path.display().to_string()
67                }
68
69                Err(()) => url.to_string(),
70            },
71
72            "libdada" => format!("[libdada] {}", url.path()),
73
74            _ => url.to_string(),
75        }
76    }
77}