Skip to main content

turbopack_core/module_graph/
module_batch.rs

1use std::fmt::Debug;
2
3use anyhow::Result;
4use bincode::{Decode, Encode};
5use serde::{Deserialize, Serialize};
6use turbo_rcstr::RcStr;
7use turbo_tasks::{ReadRef, ResolvedVc, TryJoinIterExt, ValueToString, Vc};
8
9use crate::{
10    chunk::ChunkableModule, module::Module, module_graph::chunk_group_info::RoaringBitmapWrapper,
11};
12
13#[turbo_tasks::task_input]
14#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)]
15pub enum ModuleOrBatch {
16    Module(ResolvedVc<Box<dyn Module>>),
17    Batch(ResolvedVc<ModuleBatch>),
18    None(usize),
19}
20
21impl ModuleOrBatch {
22    pub async fn ident_strings(self) -> Result<IdentStrings> {
23        Ok(match self {
24            ModuleOrBatch::Module(module) => {
25                IdentStrings::Single(module.ident().to_string().owned().await?)
26            }
27            ModuleOrBatch::Batch(batch) => IdentStrings::Multiple(batch.ident_strings().await?),
28            ModuleOrBatch::None(_) => IdentStrings::None,
29        })
30    }
31}
32
33#[turbo_tasks::task_input]
34#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Encode, Decode)]
35pub enum ChunkableModuleOrBatch {
36    Module(ResolvedVc<Box<dyn ChunkableModule>>),
37    Batch(ResolvedVc<ModuleBatch>),
38    None(usize),
39}
40
41impl ChunkableModuleOrBatch {
42    pub fn from_module_or_batch(module_or_batch: ModuleOrBatch) -> Option<Self> {
43        match module_or_batch {
44            ModuleOrBatch::Module(module) => ResolvedVc::try_downcast(module).map(Self::Module),
45            ModuleOrBatch::Batch(batch) => Some(Self::Batch(batch)),
46            ModuleOrBatch::None(i) => Some(Self::None(i)),
47        }
48    }
49
50    pub async fn ident_strings(self) -> Result<IdentStrings> {
51        Ok(match self {
52            ChunkableModuleOrBatch::Module(module) => {
53                IdentStrings::Single(module.ident().to_string().owned().await?)
54            }
55            ChunkableModuleOrBatch::Batch(batch) => {
56                IdentStrings::Multiple(batch.ident_strings().await?)
57            }
58            ChunkableModuleOrBatch::None(_) => IdentStrings::None,
59        })
60    }
61}
62
63impl From<ChunkableModuleOrBatch> for ModuleOrBatch {
64    fn from(chunkable_module_or_batch: ChunkableModuleOrBatch) -> Self {
65        match chunkable_module_or_batch {
66            ChunkableModuleOrBatch::Module(module) => Self::Module(ResolvedVc::upcast(module)),
67            ChunkableModuleOrBatch::Batch(batch) => Self::Batch(batch),
68            ChunkableModuleOrBatch::None(i) => Self::None(i),
69        }
70    }
71}
72
73pub enum IdentStrings {
74    None,
75    Single(RcStr),
76    Multiple(ReadRef<Vec<RcStr>>),
77}
78
79impl Debug for IdentStrings {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        match self {
82            IdentStrings::None => write!(f, "None"),
83            IdentStrings::Single(ident) => ident.fmt(f),
84            IdentStrings::Multiple(idents) => idents.fmt(f),
85        }
86    }
87}
88
89#[turbo_tasks::value]
90pub struct ModuleBatch {
91    pub modules: Vec<ResolvedVc<Box<dyn ChunkableModule>>>,
92    pub chunk_groups: Option<RoaringBitmapWrapper>,
93}
94
95#[turbo_tasks::value_impl]
96impl ModuleBatch {
97    #[turbo_tasks::function]
98    pub fn new(
99        modules: Vec<ResolvedVc<Box<dyn ChunkableModule>>>,
100        chunk_groups: Option<RoaringBitmapWrapper>,
101    ) -> Vc<Self> {
102        Self {
103            modules,
104            chunk_groups,
105        }
106        .cell()
107    }
108
109    #[turbo_tasks::function]
110    pub async fn ident_strings(&self) -> Result<Vc<Vec<RcStr>>> {
111        Ok(Vc::cell(
112            self.modules
113                .iter()
114                .map(|module| module.ident().to_string().owned())
115                .try_join()
116                .await?,
117        ))
118    }
119}
120
121#[turbo_tasks::value]
122pub struct ModuleBatchGroup {
123    pub items: Vec<ModuleOrBatch>,
124    pub chunk_groups: RoaringBitmapWrapper,
125}
126
127#[turbo_tasks::value_impl]
128impl ModuleBatchGroup {
129    #[turbo_tasks::function]
130    pub fn new(items: Vec<ModuleOrBatch>, chunk_groups: RoaringBitmapWrapper) -> Vc<Self> {
131        Self {
132            items,
133            chunk_groups,
134        }
135        .cell()
136    }
137}
138
139#[turbo_tasks::value]
140pub struct ChunkableModuleBatchGroup {
141    pub items: Vec<ChunkableModuleOrBatch>,
142    pub chunk_groups: RoaringBitmapWrapper,
143}
144
145#[turbo_tasks::value_impl]
146impl ChunkableModuleBatchGroup {
147    #[turbo_tasks::function]
148    pub async fn from_module_batch_group(batch_group: Vc<ModuleBatchGroup>) -> Result<Vc<Self>> {
149        let batch_group = batch_group.await?;
150        let items = batch_group
151            .items
152            .iter()
153            .filter_map(|batch| match *batch {
154                ModuleOrBatch::Module(module) => {
155                    ResolvedVc::try_downcast(module).map(ChunkableModuleOrBatch::Module)
156                }
157                ModuleOrBatch::Batch(batch) => Some(ChunkableModuleOrBatch::Batch(batch)),
158                ModuleOrBatch::None(_) => None,
159            })
160            .collect();
161        Ok(Self {
162            items,
163            chunk_groups: batch_group.chunk_groups.clone(),
164        }
165        .cell())
166    }
167}