webpack_stats/v5/
chunk.rs1use crate::common::SizeBytes;
18use crate::v5::module::Modules;
19use crate::v5::reason::Reasons;
20use serde::Deserialize;
21use std::borrow::Cow;
22
23use crate::chunk::{
24 ChunkChild, ChunkChildren, ChunkInitial, ChunkModules, ChunkParentOrSibling, Files,
25};
26use crate::common::chunk::{ChunkId, ChunkName};
27use crate::common::import::SourceFilePath;
28use crate::common::module::{ModuleId, ModuleIdentifier, RelativeModulePath};
29use meshed::prelude::*;
30
31#[derive(Debug, Default, Deserialize)]
32#[serde(transparent)]
33pub struct Chunks<'a> {
34 #[serde(borrow)]
35 pub chunks: Vec<Chunk<'a>>,
36}
37
38impl<'a> crate::common::chunk::Chunks<Chunk<'a>> for Chunks<'a> {}
39
40impl<'a> Query<ChunkId, Chunk<'a>> for Chunks<'a> {
41 fn query(&self, identifier: &ChunkId) -> Option<&Chunk<'a>> {
42 self.chunks
43 .iter()
44 .find(|chunk| &chunk.get_id() == identifier)
45 }
46
47 fn all(&self) -> Vec<&Chunk<'a>> {
48 self.chunks.iter().collect()
49 }
50}
51
52#[derive(Deserialize, Debug)]
53#[serde(rename_all = "camelCase")]
54pub struct Chunk<'a> {
55 pub id: ChunkId,
56 pub entry: bool,
57 pub initial: bool,
58 #[serde(borrow)]
59 pub modules: Modules<'a>,
60 pub files: Vec<SourceFilePath<'a>>,
61 #[serde(borrow)]
62 pub names: Vec<ChunkName<'a>>,
63 #[serde(default)]
64 pub origins: Vec<Origin<'a>>,
65 pub parents: Vec<ChunkId>,
66 pub siblings: Vec<ChunkId>,
67 pub children: Vec<ChunkId>,
68 pub rendered: bool,
69 pub size: SizeBytes,
70}
71
72impl<'a> ExtractData<ChunkId> for Chunk<'a> {
73 fn extract_data(&self) -> ChunkId {
74 self.id
75 }
76}
77
78impl<'a> ExtractData<ChunkChildren> for Chunk<'a> {
79 fn extract_data(&self) -> ChunkChildren {
80 ChunkChildren(self.children.clone())
81 }
82}
83
84impl<'a> ExtractData<SizeBytes> for Chunk<'a> {
85 fn extract_data(&self) -> SizeBytes {
86 self.size
87 }
88}
89
90impl<'a> ExtractData<ChunkModules> for Chunk<'a> {
91 fn extract_data(&self) -> ChunkModules {
92 self.modules
93 .modules
94 .iter()
95 .map(|module| module.identifier.clone())
96 .collect()
97 }
98}
99
100impl<'a> Label for Chunk<'a> {
101 type Label = ChunkId;
102
103 fn label(&self) -> Self::Label {
104 self.id
105 }
106}
107
108impl<'a> ExtractData<ChunkInitial> for Chunk<'a> {
109 fn extract_data(&self) -> ChunkInitial {
110 ChunkInitial(self.initial)
111 }
112}
113
114impl<'a> ExtractData<Files> for Chunk<'a> {
115 fn extract_data(&self) -> Files {
116 Files(
117 self.files
118 .iter()
119 .map(|f| f.0.to_string_lossy().to_string())
120 .collect(),
121 )
122 }
123}
124
125impl<'a> crate::common::chunk::Chunk for Chunk<'a> {}
126
127impl<'a> Identifiable<ChunkId> for Chunk<'a> {
128 fn get_id(&self) -> ChunkId {
129 self.id
130 }
131}
132
133impl<'a> Edges<ChunkId, ChunkParentOrSibling> for Chunk<'a> {
134 fn next_edge(
135 &self,
136 previous_edge_index: Option<usize>,
137 ) -> Option<Edge<ChunkId, ChunkParentOrSibling>> {
138 let next_idx = previous_edge_index.map(|e| e + 1).unwrap_or_default();
139 let data = if next_idx < self.siblings.len() {
140 self.siblings.get(next_idx).cloned()?
141 } else {
142 self.parents.get(next_idx - self.siblings.len()).cloned()?
143 };
144
145 Some(Edge::new(
146 self.get_id(),
147 data,
148 next_idx,
149 ChunkParentOrSibling,
150 ))
151 }
152}
153
154impl<'a> Edges<ChunkId, ChunkChild> for Chunk<'a> {
155 fn next_edge(&self, previous_edge_index: Option<usize>) -> Option<Edge<ChunkId, ChunkChild>> {
156 let next_idx = previous_edge_index.map(|e| e + 1).unwrap_or_default();
157 let data = self.children.get(next_idx).cloned()?;
158
159 Some(Edge::new(self.get_id(), data, next_idx, ChunkChild))
160 }
161}
162
163#[derive(Deserialize, Debug)]
164#[serde(rename_all = "camelCase")]
165pub struct Origin<'a> {
166 #[serde(borrow)]
167 pub loc: Cow<'a, str>,
168 pub module_identifier: ModuleIdentifier,
169 #[serde(default)]
170 pub module_id: Option<ModuleId>,
171 pub module_name: RelativeModulePath<'a>,
172 #[serde(default)]
173 pub reasons: Reasons<'a>,
174}