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, rcstr};
5use turbo_tasks::{ValueToString, Vc};
6
7use crate::{
8    File, FileContent, FileMeta, FileSystem, FileSystemPath, LinkContent, RawDirectoryContent,
9    RawDirectoryEntry, WriteLinkContent,
10};
11
12#[derive(ValueToString)]
13#[value_to_string(self.name)]
14#[turbo_tasks::value(serialization = "skip", 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::Invalid {
42            reason: rcstr!("the filesystem does not support symbolic links"),
43        }
44        .cell()
45    }
46
47    #[turbo_tasks::function]
48    fn is_junction_point(&self, _path: FileSystemPath) -> Vc<bool> {
49        Vc::cell(false)
50    }
51
52    #[turbo_tasks::function]
53    async fn raw_read_dir(&self, path: FileSystemPath) -> Result<Vc<RawDirectoryContent>> {
54        let path_str = &path.path;
55        let dir = match (path_str.as_str(), self.dir.get_dir(path_str)) {
56            ("", _) => self.dir,
57            (_, Some(dir)) => dir,
58            (_, None) => return Ok(RawDirectoryContent::NotFound.cell()),
59        };
60
61        let mut converted_entries = AutoMap::new();
62        for e in dir.entries() {
63            let entry_name: RcStr = e
64                .path()
65                .file_name()
66                .unwrap_or_default()
67                .to_string_lossy()
68                .into();
69
70            converted_entries.insert(
71                entry_name,
72                match e {
73                    DirEntry::Dir(_) => RawDirectoryEntry::Directory,
74                    DirEntry::File(_) => RawDirectoryEntry::File,
75                },
76            );
77        }
78
79        Ok(RawDirectoryContent::new(converted_entries))
80    }
81
82    #[turbo_tasks::function]
83    fn write(&self, _path: FileSystemPath, _content: Vc<FileContent>) -> Result<Vc<()>> {
84        bail!("Writing is not possible to the embedded filesystem")
85    }
86
87    #[turbo_tasks::function]
88    fn write_link(&self, _path: FileSystemPath, _target: Vc<WriteLinkContent>) -> Result<Vc<()>> {
89        bail!("Writing is not possible to the embedded filesystem")
90    }
91
92    #[turbo_tasks::function]
93    async fn metadata(&self, path: FileSystemPath) -> Result<Vc<FileMeta>> {
94        if self.dir.get_entry(&path.path).is_none() {
95            bail!("path not found, can't read metadata");
96        }
97
98        Ok(FileMeta::default().cell())
99    }
100}