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