1use std::hash::Hash;
2
3use anyhow::Result;
4use turbo_tasks::{ResolvedVc, TryJoinIterExt, Vc};
5use turbo_tasks_fs::FileSystemPath;
6
7use crate::{
8 asset::{Asset, AssetContent},
9 module::Module,
10 output::{OutputAsset, OutputAssets},
11 reference::referenced_modules_and_affecting_sources,
12};
13
14#[turbo_tasks::value]
17#[derive(Hash)]
18pub struct RebasedAsset {
19 module: ResolvedVc<Box<dyn Module>>,
20 input_dir: ResolvedVc<FileSystemPath>,
21 output_dir: ResolvedVc<FileSystemPath>,
22}
23
24#[turbo_tasks::value_impl]
25impl RebasedAsset {
26 #[turbo_tasks::function]
27 pub fn new(
28 module: ResolvedVc<Box<dyn Module>>,
29 input_dir: ResolvedVc<FileSystemPath>,
30 output_dir: ResolvedVc<FileSystemPath>,
31 ) -> Vc<Self> {
32 Self::cell(RebasedAsset {
33 module,
34 input_dir,
35 output_dir,
36 })
37 }
38}
39
40#[turbo_tasks::value_impl]
41impl OutputAsset for RebasedAsset {
42 #[turbo_tasks::function]
43 fn path(&self) -> Vc<FileSystemPath> {
44 FileSystemPath::rebase(
45 self.module.ident().path(),
46 *self.input_dir,
47 *self.output_dir,
48 )
49 }
50
51 #[turbo_tasks::function]
52 async fn references(&self) -> Result<Vc<OutputAssets>> {
53 let references = referenced_modules_and_affecting_sources(*self.module)
54 .await?
55 .iter()
56 .map(|module| async move {
57 Ok(ResolvedVc::upcast(
58 RebasedAsset::new(**module, *self.input_dir, *self.output_dir)
59 .to_resolved()
60 .await?,
61 ))
62 })
63 .try_join()
64 .await?;
65 Ok(Vc::cell(references))
66 }
67}
68
69#[turbo_tasks::value_impl]
70impl Asset for RebasedAsset {
71 #[turbo_tasks::function]
72 fn content(&self) -> Vc<AssetContent> {
73 self.module.content()
74 }
75}