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, OutputAssetsReference, OutputAssetsWithReferenced},
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: FileSystemPath,
21    output_dir: 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: FileSystemPath,
30        output_dir: 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 OutputAssetsReference for RebasedAsset {
42    #[turbo_tasks::function]
43    async fn references(&self) -> Result<Vc<OutputAssetsWithReferenced>> {
44        let references = referenced_modules_and_affecting_sources(*self.module)
45            .await?
46            .iter()
47            .map(|module| async move {
48                Ok(ResolvedVc::upcast(
49                    RebasedAsset::new(**module, self.input_dir.clone(), self.output_dir.clone())
50                        .to_resolved()
51                        .await?,
52                ))
53            })
54            .try_join()
55            .await?;
56        Ok(OutputAssetsWithReferenced::from_assets(Vc::cell(
57            references,
58        )))
59    }
60}
61
62#[turbo_tasks::value_impl]
63impl OutputAsset for RebasedAsset {
64    #[turbo_tasks::function]
65    async fn path(&self) -> Result<Vc<FileSystemPath>> {
66        Ok(FileSystemPath::rebase(
67            self.module.ident().path().owned().await?,
68            self.input_dir.clone(),
69            self.output_dir.clone(),
70        ))
71    }
72}
73
74#[turbo_tasks::value_impl]
75impl Asset for RebasedAsset {
76    #[turbo_tasks::function]
77    fn content(&self) -> Vc<AssetContent> {
78        self.module.content()
79    }
80}