Skip to main content

turbopack_core/chunk/
availability_info.rs

1use anyhow::Result;
2use bincode::{Decode, Encode};
3use bitfield::bitfield;
4use turbo_rcstr::RcStr;
5use turbo_tasks::{OperationVc, ResolvedVc, trace::TraceRawVcs};
6
7use crate::{
8    chunk::available_modules::{AvailableModules, AvailableModulesSet},
9    module::Modules,
10};
11
12bitfield! {
13    #[turbo_tasks::task_input]
14    #[derive(Clone, Copy, Default, TraceRawVcs, PartialEq, Eq, Hash, Encode, Decode)]
15    pub struct AvailabilityFlags(u8);
16    impl Debug;
17    pub is_in_async_module, set_is_in_async_module: 0;
18}
19
20#[turbo_tasks::task_input]
21#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug, TraceRawVcs, Encode, Decode)]
22pub struct AvailabilityInfo {
23    flags: AvailabilityFlags,
24    /// There are modules already available.
25    available_modules: Option<ResolvedVc<AvailableModules>>,
26    /// The root ChunkGroup::Entry
27    entry_group: Option<ResolvedVc<Modules>>,
28}
29
30impl AvailabilityInfo {
31    pub fn root() -> Self {
32        Self {
33            flags: AvailabilityFlags::default(),
34            available_modules: None,
35            entry_group: None,
36        }
37    }
38
39    pub fn available_modules(&self) -> Option<ResolvedVc<AvailableModules>> {
40        self.available_modules
41    }
42
43    pub async fn with_modules(self, modules: OperationVc<AvailableModulesSet>) -> Result<Self> {
44        Ok(if let Some(available_modules) = self.available_modules {
45            Self {
46                flags: self.flags,
47                available_modules: Some(
48                    available_modules
49                        .with_modules(modules)
50                        .to_resolved()
51                        .await?,
52                ),
53                entry_group: self.entry_group,
54            }
55        } else {
56            Self {
57                flags: self.flags,
58                available_modules: Some(AvailableModules::new(modules).to_resolved().await?),
59                entry_group: self.entry_group,
60            }
61        })
62    }
63
64    pub fn in_async_module(self) -> Self {
65        let mut flags = self.flags;
66        flags.set_is_in_async_module(true);
67        Self {
68            flags,
69            available_modules: self.available_modules,
70            entry_group: self.entry_group,
71        }
72    }
73
74    pub fn is_in_async_module(&self) -> bool {
75        self.flags.is_in_async_module()
76    }
77
78    pub fn with_entry_group(self, entry_group: ResolvedVc<Modules>) -> Self {
79        Self {
80            flags: self.flags,
81            available_modules: self.available_modules,
82            entry_group: Some(entry_group),
83        }
84    }
85
86    pub fn entry_group(&self) -> Option<ResolvedVc<Modules>> {
87        self.entry_group
88    }
89
90    pub async fn ident(&self) -> Result<Option<RcStr>> {
91        Ok(if let Some(available_modules) = self.available_modules {
92            Some(available_modules.hash().await?.to_string().into())
93        } else {
94            None
95        })
96    }
97}