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