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};
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}