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