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