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