turbopack_core/
file_source.rs1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbo_tasks_fs::{FileContent, FileSystemEntryType, FileSystemPath, LinkContent};
5
6use crate::{
7 asset::{Asset, AssetContent},
8 ident::AssetIdent,
9 source::Source,
10};
11
12#[turbo_tasks::value]
15pub struct FileSource {
16 pub path: ResolvedVc<FileSystemPath>,
17 pub query: ResolvedVc<RcStr>,
18}
19
20#[turbo_tasks::value_impl]
21impl FileSource {
22 #[turbo_tasks::function]
23 pub fn new(path: ResolvedVc<FileSystemPath>) -> Vc<Self> {
24 Self::cell(FileSource {
25 path,
26 query: ResolvedVc::cell(RcStr::default()),
27 })
28 }
29
30 #[turbo_tasks::function]
31 pub async fn new_with_query(
32 path: ResolvedVc<FileSystemPath>,
33 query: ResolvedVc<RcStr>,
34 ) -> Result<Vc<Self>> {
35 if query.await?.is_empty() {
36 Ok(Self::new(*path))
37 } else {
38 Ok(Self::cell(FileSource { path, query }))
39 }
40 }
41}
42
43#[turbo_tasks::value_impl]
44impl Source for FileSource {
45 #[turbo_tasks::function]
46 fn ident(&self) -> Vc<AssetIdent> {
47 AssetIdent::from_path(*self.path).with_query(*self.query)
48 }
49}
50
51#[turbo_tasks::value_impl]
52impl Asset for FileSource {
53 #[turbo_tasks::function]
54 async fn content(&self) -> Result<Vc<AssetContent>> {
55 let file_type = &*self.path.get_type().await?;
56 match file_type {
57 FileSystemEntryType::Symlink => match &*self.path.read_link().await? {
58 LinkContent::Link { target, link_type } => Ok(AssetContent::Redirect {
59 target: target.clone(),
60 link_type: *link_type,
61 }
62 .cell()),
63 _ => Err(anyhow::anyhow!("Invalid symlink")),
64 },
65 FileSystemEntryType::File => {
66 Ok(AssetContent::File(self.path.read().to_resolved().await?).cell())
67 }
68 FileSystemEntryType::NotFound => {
69 Ok(AssetContent::File(FileContent::NotFound.resolved_cell()).cell())
70 }
71 _ => Err(anyhow::anyhow!("Invalid file type {:?}", file_type)),
72 }
73 }
74}