turbopack_core/
rebase.rs

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/// Converts a [Module] graph into an [OutputAsset] graph by placing it into a
15/// different directory.
16#[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}