turbo_tasks_fs/embed/
fs.rs1use 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}