1use serde::Serialize;
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
7#[serde(rename_all = "camelCase")]
8pub struct ModuleIdV0(String);
9
10impl ModuleIdV0 {
11 pub fn new(value: impl Into<String>) -> Self {
12 Self(value.into())
13 }
14
15 pub fn as_str(&self) -> &str {
16 &self.0
17 }
18}
19
20impl From<&str> for ModuleIdV0 {
21 fn from(value: &str) -> Self {
22 Self::new(value)
23 }
24}
25
26impl From<String> for ModuleIdV0 {
27 fn from(value: String) -> Self {
28 Self::new(value)
29 }
30}
31
32#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
33#[serde(rename_all = "camelCase")]
34pub struct ConfigurationHashV0(String);
35
36impl ConfigurationHashV0 {
37 pub fn new(value: impl Into<String>) -> Self {
38 Self(value.into())
39 }
40
41 pub fn none() -> Self {
42 Self::new("with:none")
43 }
44
45 pub fn as_str(&self) -> &str {
46 &self.0
47 }
48}
49
50impl Default for ConfigurationHashV0 {
51 fn default() -> Self {
52 Self::none()
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
57#[serde(rename_all = "camelCase")]
58pub struct ModuleInstanceKeyV0 {
59 module: ModuleIdV0,
60 configuration: ConfigurationHashV0,
61}
62
63impl ModuleInstanceKeyV0 {
64 pub fn new(module: ModuleIdV0, configuration: ConfigurationHashV0) -> Self {
65 Self {
66 module,
67 configuration,
68 }
69 }
70
71 pub fn unconfigured(module: ModuleIdV0) -> Self {
72 Self::new(module, ConfigurationHashV0::none())
73 }
74
75 pub fn module(&self) -> &ModuleIdV0 {
76 &self.module
77 }
78
79 pub fn configuration(&self) -> &ConfigurationHashV0 {
80 &self.configuration
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
85#[serde(rename_all = "camelCase")]
86pub struct ClosedWorldLinkedModuleV0 {
87 pub instance: ModuleInstanceKeyV0,
88 pub dependencies: Vec<ModuleInstanceKeyV0>,
89 pub class_names: Vec<String>,
90 pub keyframe_names: Vec<String>,
91 pub value_names: Vec<String>,
92 pub custom_property_names: Vec<String>,
93}
94
95impl ClosedWorldLinkedModuleV0 {
96 pub fn new(instance: ModuleInstanceKeyV0) -> Self {
97 Self {
98 instance,
99 dependencies: Vec::new(),
100 class_names: Vec::new(),
101 keyframe_names: Vec::new(),
102 value_names: Vec::new(),
103 custom_property_names: Vec::new(),
104 }
105 }
106
107 pub fn with_dependency(mut self, dependency: ModuleInstanceKeyV0) -> Self {
108 self.dependencies.push(dependency);
109 self
110 }
111
112 pub fn with_class_name(mut self, name: impl Into<String>) -> Self {
113 self.class_names.push(name.into());
114 self
115 }
116
117 pub fn with_keyframe_name(mut self, name: impl Into<String>) -> Self {
118 self.keyframe_names.push(name.into());
119 self
120 }
121
122 pub fn with_value_name(mut self, name: impl Into<String>) -> Self {
123 self.value_names.push(name.into());
124 self
125 }
126
127 pub fn with_custom_property_name(mut self, name: impl Into<String>) -> Self {
128 self.custom_property_names.push(name.into());
129 self
130 }
131}
132
133#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize)]
134#[serde(rename_all = "camelCase")]
135pub struct ClosedWorldSourcePrecisionSummaryV0 {
136 pub exact_source_count: usize,
137 pub conservative_source_count: usize,
138 pub heuristic_source_count: usize,
139 pub unknown_source_count: usize,
140}
141
142impl ClosedWorldSourcePrecisionSummaryV0 {
143 pub(crate) fn merge(&mut self, other: Self) {
144 self.exact_source_count = self
145 .exact_source_count
146 .saturating_add(other.exact_source_count);
147 self.conservative_source_count = self
148 .conservative_source_count
149 .saturating_add(other.conservative_source_count);
150 self.heuristic_source_count = self
151 .heuristic_source_count
152 .saturating_add(other.heuristic_source_count);
153 self.unknown_source_count = self
154 .unknown_source_count
155 .saturating_add(other.unknown_source_count);
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct ClosedWorldModuleMetadataV0 {
161 module_instance: ModuleInstanceKeyV0,
162 interface_hash: Option<String>,
163 source_precision: Option<ClosedWorldSourcePrecisionSummaryV0>,
164}
165
166impl ClosedWorldModuleMetadataV0 {
167 pub fn new(module_instance: ModuleInstanceKeyV0) -> Self {
168 Self {
169 module_instance,
170 interface_hash: None,
171 source_precision: None,
172 }
173 }
174
175 pub fn module_instance(&self) -> &ModuleInstanceKeyV0 {
176 &self.module_instance
177 }
178
179 pub fn with_interface_hash(mut self, interface_hash: impl Into<String>) -> Self {
180 self.interface_hash = Some(interface_hash.into());
181 self
182 }
183
184 pub fn interface_hash(&self) -> Option<&str> {
185 self.interface_hash.as_deref()
186 }
187
188 pub fn with_source_precision(
189 mut self,
190 source_precision: ClosedWorldSourcePrecisionSummaryV0,
191 ) -> Self {
192 self.source_precision = Some(source_precision);
193 self
194 }
195
196 pub fn source_precision(&self) -> Option<ClosedWorldSourcePrecisionSummaryV0> {
197 self.source_precision
198 }
199}
200
201#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
202#[serde(rename_all = "camelCase", tag = "status")]
203pub enum ClosedWorldInterfaceHashAvailabilityV0 {
204 Known { interface_hash: String },
205 Absent,
206}
207
208#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
209#[serde(rename_all = "camelCase")]
210pub struct ClosedWorldInterfaceHashEntryV0 {
211 pub module_instance: ModuleInstanceKeyV0,
212 pub availability: ClosedWorldInterfaceHashAvailabilityV0,
213}
214
215#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
216#[serde(rename_all = "camelCase")]
217pub struct ClosedWorldInterfaceHashSetV0 {
218 entries: Vec<ClosedWorldInterfaceHashEntryV0>,
219}
220
221impl ClosedWorldInterfaceHashSetV0 {
222 pub(crate) fn new(entries: Vec<ClosedWorldInterfaceHashEntryV0>) -> Self {
223 Self { entries }
224 }
225
226 pub fn entries(&self) -> &[ClosedWorldInterfaceHashEntryV0] {
227 &self.entries
228 }
229
230 pub fn all_absent(&self) -> bool {
231 self.entries.iter().all(|entry| {
232 matches!(
233 entry.availability,
234 ClosedWorldInterfaceHashAvailabilityV0::Absent
235 )
236 })
237 }
238}
239
240#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
241#[serde(rename_all = "camelCase")]
242pub struct ModuleQualifiedSymbolSetV0 {
243 module_instance: ModuleInstanceKeyV0,
244 reachable: bool,
245 class_names: Vec<String>,
246 keyframe_names: Vec<String>,
247 value_names: Vec<String>,
248 custom_property_names: Vec<String>,
249}
250
251impl ModuleQualifiedSymbolSetV0 {
252 pub(crate) fn new(
253 module_instance: ModuleInstanceKeyV0,
254 reachable: bool,
255 class_names: Vec<String>,
256 keyframe_names: Vec<String>,
257 value_names: Vec<String>,
258 custom_property_names: Vec<String>,
259 ) -> Self {
260 Self {
261 module_instance,
262 reachable,
263 class_names,
264 keyframe_names,
265 value_names,
266 custom_property_names,
267 }
268 }
269
270 pub fn module_instance(&self) -> &ModuleInstanceKeyV0 {
271 &self.module_instance
272 }
273
274 pub fn is_reachable(&self) -> bool {
275 self.reachable
276 }
277
278 pub fn class_names(&self) -> &[String] {
279 &self.class_names
280 }
281
282 pub fn keyframe_names(&self) -> &[String] {
283 &self.keyframe_names
284 }
285
286 pub fn value_names(&self) -> &[String] {
287 &self.value_names
288 }
289
290 pub fn custom_property_names(&self) -> &[String] {
291 &self.custom_property_names
292 }
293}
294
295#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
296#[serde(rename_all = "camelCase")]
297pub struct ReachabilityIndexV0 {
298 module_instances: Vec<ModuleInstanceKeyV0>,
299 module_qualified_symbols: Vec<ModuleQualifiedSymbolSetV0>,
300 class_names: Vec<String>,
301 keyframe_names: Vec<String>,
302 value_names: Vec<String>,
303 custom_property_names: Vec<String>,
304}
305
306impl ReachabilityIndexV0 {
307 pub(crate) fn from_parts(
308 module_instances: Vec<ModuleInstanceKeyV0>,
309 module_qualified_symbols: Vec<ModuleQualifiedSymbolSetV0>,
310 class_names: Vec<String>,
311 keyframe_names: Vec<String>,
312 value_names: Vec<String>,
313 custom_property_names: Vec<String>,
314 ) -> Self {
315 Self {
316 module_instances,
317 module_qualified_symbols,
318 class_names,
319 keyframe_names,
320 value_names,
321 custom_property_names,
322 }
323 }
324
325 pub fn module_instances(&self) -> &[ModuleInstanceKeyV0] {
326 &self.module_instances
327 }
328
329 pub fn module_qualified_symbols(&self) -> &[ModuleQualifiedSymbolSetV0] {
330 &self.module_qualified_symbols
331 }
332
333 pub fn symbols_for_module(
334 &self,
335 module_instance: &ModuleInstanceKeyV0,
336 ) -> Option<&ModuleQualifiedSymbolSetV0> {
337 self.module_qualified_symbols
338 .binary_search_by(|entry| entry.module_instance().cmp(module_instance))
339 .ok()
340 .map(|index| &self.module_qualified_symbols[index])
341 }
342
343 pub fn class_names(&self) -> &[String] {
344 &self.class_names
345 }
346
347 pub fn keyframe_names(&self) -> &[String] {
348 &self.keyframe_names
349 }
350
351 pub fn value_names(&self) -> &[String] {
352 &self.value_names
353 }
354
355 pub fn custom_property_names(&self) -> &[String] {
356 &self.custom_property_names
357 }
358}
359
360#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
361#[serde(rename_all = "camelCase")]
362pub struct ClosedWorldReachabilityBitsetParityReportV0 {
363 pub schema_version: &'static str,
364 pub product: &'static str,
365 pub module_instance_count: usize,
366 pub symbol_name_count: usize,
367 pub module_qualified_symbols: Vec<ModuleQualifiedSymbolSetV0>,
368 pub reachability_equal: bool,
369 pub closure_hash_equal: bool,
370 pub btreeset_closure_hash: String,
371 pub bitset_closure_hash: String,
372}
373
374#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
386#[serde(rename_all = "camelCase")]
387pub struct ClosedWorldBundleV0 {
388 entrypoints: Vec<ModuleInstanceKeyV0>,
389 linked_modules: Vec<ModuleInstanceKeyV0>,
390 reachability: ReachabilityIndexV0,
391 closure_hash: String,
392 #[serde(skip_serializing_if = "ClosedWorldInterfaceHashSetV0::all_absent")]
393 interface_hashes: ClosedWorldInterfaceHashSetV0,
394 #[serde(skip_serializing_if = "Option::is_none")]
395 source_precision: Option<ClosedWorldSourcePrecisionSummaryV0>,
396}
397
398impl ClosedWorldBundleV0 {
399 pub(crate) fn seal(
400 entrypoints: Vec<ModuleInstanceKeyV0>,
401 linked_modules: Vec<ModuleInstanceKeyV0>,
402 reachability: ReachabilityIndexV0,
403 closure_hash: String,
404 interface_hashes: ClosedWorldInterfaceHashSetV0,
405 source_precision: Option<ClosedWorldSourcePrecisionSummaryV0>,
406 ) -> Self {
407 Self {
408 entrypoints,
409 linked_modules,
410 reachability,
411 closure_hash,
412 interface_hashes,
413 source_precision,
414 }
415 }
416
417 pub fn entrypoints(&self) -> &[ModuleInstanceKeyV0] {
418 &self.entrypoints
419 }
420
421 pub fn linked_modules(&self) -> &[ModuleInstanceKeyV0] {
422 &self.linked_modules
423 }
424
425 pub fn reachability(&self) -> &ReachabilityIndexV0 {
426 &self.reachability
427 }
428
429 pub fn closure_hash(&self) -> &str {
430 &self.closure_hash
431 }
432
433 pub fn interface_hashes(&self) -> &ClosedWorldInterfaceHashSetV0 {
434 &self.interface_hashes
435 }
436
437 pub fn source_precision(&self) -> Option<ClosedWorldSourcePrecisionSummaryV0> {
438 self.source_precision
439 }
440}
441
442#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
443#[serde(rename_all = "camelCase")]
444pub struct OpenWorldSnapshotV0 {
445 reason: String,
446}
447
448impl OpenWorldSnapshotV0 {
449 pub fn new(reason: impl Into<String>) -> Self {
450 Self {
451 reason: reason.into(),
452 }
453 }
454
455 pub fn reason(&self) -> &str {
456 &self.reason
457 }
458}
459
460#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
461#[serde(rename_all = "camelCase")]
462pub enum ClosedWorldBundleBuildErrorV0 {
463 EmptyEntrypoints,
464 MissingEntrypoint {
465 module: ModuleInstanceKeyV0,
466 },
467 MissingDependency {
468 module: ModuleInstanceKeyV0,
469 dependency: ModuleInstanceKeyV0,
470 },
471}