Skip to main content

turbo_tasks_fs/embed/
fs.rs

1use anyhow::{Result, bail};
2use auto_hash_map::AutoMap;
3use include_dir::{Dir, DirEntry};
4use turbo_rcstr::RcStr;
5use turbo_tasks::{ValueToString, Vc};
6
7use crate::{
8    File, FileContent, FileMeta, FileSystem, FileSystemPath, LinkContent, RawDirectoryContent,
9    RawDirectoryEntry,
10};
11
12#[derive(ValueToString)]
13#[value_to_string(self.name)]
14#[turbo_tasks::value(serialization = "none", cell = "new", eq = "manual")]
15pub struct EmbeddedFileSystem {
16    name: RcStr,
17    #[turbo_tasks(trace_ignore)]
18    dir: &'static Dir<'static>,
19}
20
21impl EmbeddedFileSystem {
22    pub(super) fn new(name: RcStr, dir: &'static Dir<'static>) -> Vc<EmbeddedFileSystem> {
23        EmbeddedFileSystem { name, dir }.cell()
24    }
25}
26
27#[turbo_tasks::value_impl]
28impl FileSystem for EmbeddedFileSystem {
29    #[turbo_tasks::function]
30    async fn read(&self, path: FileSystemPath) -> Result<Vc<FileContent>> {
31        let file = match self.dir.get_file(&path.path) {
32            Some(file) => file,
33            None => return Ok(FileContent::NotFound.cell()),
34        };
35
36        Ok(FileContent::Content(File::from(file.contents())).cell())
37    }
38
39    #[turbo_tasks::function]
40    fn read_link(&self, _path: FileSystemPath) -> Vc<LinkContent> {
41        LinkContent::NotFound.cell()
42    }
43
44    #[turbo_tasks::function]
45    async fn raw_read_dir(&self, path: FileSystemPath) -> Result<Vc<RawDirectoryContent>> {
46        let path_str = &path.path;
47        let dir = match (path_str.as_str(), self.dir.get_dir(path_str)) {
48            ("", _) => self.dir,
49            (_, Some(dir)) => dir,
50            (_, None) => return Ok(RawDirectoryContent::NotFound.cell()),
51        };
52
53        let mut converted_entries = AutoMap::new();
54        for e in dir.entries() {
55            let entry_name: RcStr = e
56                .path()
57                .file_name()
58                .unwrap_or_default()
59                .to_string_lossy()
60                .into();
61
62            converted_entries.insert(
63                entry_name,
64                match e {
65                    DirEntry::Dir(_) => RawDirectoryEntry::Directory,
66                    DirEntry::File(_) => RawDirectoryEntry::File,
67                },
68            );
69        }
70
71        Ok(RawDirectoryContent::new(converted_entries))
72    }
73
74    #[turbo_tasks::function]
75    fn write(&self, _path: FileSystemPath, _content: Vc<FileContent>) -> Result<Vc<()>> {
76        bail!("Writing is not possible to the embedded filesystem")
77    }
78
79    #[turbo_tasks::function]
80    fn write_link(&self, _path: FileSystemPath, _target: Vc<LinkContent>) -> Result<Vc<()>> {
81        bail!("Writing is not possible to the embedded filesystem")
82    }
83
84    #[turbo_tasks::function]
85    async fn metadata(&self, path: FileSystemPath) -> Result<Vc<FileMeta>> {
86        if self.dir.get_entry(&path.path).is_none() {
87            bail!("path not found, can't read metadata");
88        }
89
90        Ok(FileMeta::default().cell())
91    }
92}