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