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