1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbo_tasks_fs::{
5 FileContent, FileJsonContent, FileLinesContent, FileSystemPath, LinkContent, LinkType,
6};
7
8use crate::version::{VersionedAssetContent, VersionedContent};
9
10#[turbo_tasks::value_trait]
12pub trait Asset {
13 fn content(self: Vc<Self>) -> Vc<AssetContent>;
15
16 async fn versioned_content(self: Vc<Self>) -> Result<Vc<Box<dyn VersionedContent>>> {
18 Ok(Vc::upcast(VersionedAssetContent::new(self.content())))
19 }
20}
21
22#[turbo_tasks::value(shared)]
23#[derive(Clone)]
24pub enum AssetContent {
25 File(ResolvedVc<FileContent>),
26 Redirect { target: RcStr, link_type: LinkType },
30}
31
32#[turbo_tasks::value_impl]
33impl AssetContent {
34 #[turbo_tasks::function]
35 pub async fn file(file: ResolvedVc<FileContent>) -> Result<Vc<Self>> {
36 Ok(AssetContent::File(file).cell())
37 }
38
39 #[turbo_tasks::function]
40 pub async fn parse_json(self: Vc<Self>) -> Result<Vc<FileJsonContent>> {
41 let this = self.await?;
42 match &*this {
43 AssetContent::File(content) => Ok(content.parse_json()),
44 AssetContent::Redirect { .. } => {
45 Ok(FileJsonContent::unparseable("a redirect can't be parsed as json").cell())
46 }
47 }
48 }
49
50 #[turbo_tasks::function]
51 pub async fn file_content(self: Vc<Self>) -> Result<Vc<FileContent>> {
52 let this = self.await?;
53 match &*this {
54 AssetContent::File(content) => Ok(**content),
55 AssetContent::Redirect { .. } => Ok(FileContent::NotFound.cell()),
56 }
57 }
58
59 #[turbo_tasks::function]
60 pub async fn lines(self: Vc<Self>) -> Result<Vc<FileLinesContent>> {
61 let this = self.await?;
62 match &*this {
63 AssetContent::File(content) => Ok(content.lines()),
64 AssetContent::Redirect { .. } => Ok(FileLinesContent::Unparseable.cell()),
65 }
66 }
67
68 #[turbo_tasks::function]
69 pub async fn len(self: Vc<Self>) -> Result<Vc<Option<u64>>> {
70 let this = self.await?;
71 match &*this {
72 AssetContent::File(content) => Ok(content.len()),
73 AssetContent::Redirect { .. } => Ok(Vc::cell(None)),
74 }
75 }
76
77 #[turbo_tasks::function]
78 pub async fn parse_json_with_comments(self: Vc<Self>) -> Result<Vc<FileJsonContent>> {
79 let this = self.await?;
80 match &*this {
81 AssetContent::File(content) => Ok(content.parse_json_with_comments()),
82 AssetContent::Redirect { .. } => {
83 Ok(FileJsonContent::unparseable("a redirect can't be parsed as json").cell())
84 }
85 }
86 }
87
88 #[turbo_tasks::function]
89 pub async fn write(self: Vc<Self>, path: Vc<FileSystemPath>) -> Result<()> {
90 let this = self.await?;
91 match &*this {
92 AssetContent::File(file) => {
93 let _ = path.write(**file);
94 }
95 AssetContent::Redirect { target, link_type } => {
96 let _ = path.write_link(
97 LinkContent::Link {
98 target: target.clone(),
99 link_type: *link_type,
100 }
101 .cell(),
102 );
103 }
104 }
105 Ok(())
106 }
107}