constellation_traits/structured_data/
mod.rs1mod serializable;
9mod transferable;
10
11use std::collections::HashMap;
12
13use base::id::{
14 BlobId, DomExceptionId, DomMatrixId, DomPointId, DomQuadId, DomRectId, ImageBitmapId,
15 MessagePortId, OffscreenCanvasId, QuotaExceededErrorId,
16};
17use log::warn;
18use malloc_size_of_derive::MallocSizeOf;
19use serde::{Deserialize, Serialize};
20pub use serializable::*;
21use strum::IntoEnumIterator;
22pub use transferable::*;
23
24#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
27pub struct StructuredSerializedData {
28 pub serialized: Vec<u8>,
30 pub blobs: Option<HashMap<BlobId, BlobImpl>>,
32 pub points: Option<HashMap<DomPointId, DomPoint>>,
34 pub rects: Option<HashMap<DomRectId, DomRect>>,
36 pub quads: Option<HashMap<DomQuadId, DomQuad>>,
38 pub matrices: Option<HashMap<DomMatrixId, DomMatrix>>,
40 pub exceptions: Option<HashMap<DomExceptionId, DomException>>,
42 pub quota_exceeded_errors:
44 Option<HashMap<QuotaExceededErrorId, SerializableQuotaExceededError>>,
45 pub ports: Option<HashMap<MessagePortId, MessagePortImpl>>,
47 pub transform_streams: Option<HashMap<MessagePortId, TransformStreamData>>,
49 pub image_bitmaps: Option<HashMap<ImageBitmapId, SerializableImageBitmap>>,
51 pub transferred_image_bitmaps: Option<HashMap<ImageBitmapId, SerializableImageBitmap>>,
53 pub offscreen_canvases: Option<HashMap<OffscreenCanvasId, TransferableOffscreenCanvas>>,
55}
56
57impl StructuredSerializedData {
58 fn is_empty(&self, val: Transferrable) -> bool {
59 fn is_field_empty<K, V>(field: &Option<HashMap<K, V>>) -> bool {
60 field.as_ref().is_none_or(|h| h.is_empty())
61 }
62 match val {
63 Transferrable::ImageBitmap => is_field_empty(&self.transferred_image_bitmaps),
64 Transferrable::MessagePort => is_field_empty(&self.ports),
65 Transferrable::OffscreenCanvas => is_field_empty(&self.offscreen_canvases),
66 Transferrable::ReadableStream => is_field_empty(&self.ports),
67 Transferrable::WritableStream => is_field_empty(&self.ports),
68 Transferrable::TransformStream => is_field_empty(&self.ports),
69 }
70 }
71
72 fn clone_all_of_type<T: BroadcastClone>(&self, cloned: &mut StructuredSerializedData) {
75 let existing = T::source(self);
76 let Some(existing) = existing else { return };
77 let mut clones = HashMap::with_capacity(existing.len());
78
79 for (original_id, obj) in existing.iter() {
80 if let Some(clone) = obj.clone_for_broadcast() {
81 clones.insert(*original_id, clone);
82 }
83 }
84
85 *T::destination(cloned) = Some(clones);
86 }
87
88 pub fn clone_for_broadcast(&self) -> StructuredSerializedData {
90 for transferrable in Transferrable::iter() {
91 if !self.is_empty(transferrable) {
92 warn!(
94 "Attempt to broadcast structured serialized data including {:?} (should never happen).",
95 transferrable,
96 );
97 }
98 }
99
100 let serialized = self.serialized.clone();
101
102 let mut cloned = StructuredSerializedData {
103 serialized,
104 ..Default::default()
105 };
106
107 for serializable in Serializable::iter() {
108 let clone_impl = serializable.clone_values();
109 clone_impl(self, &mut cloned);
110 }
111
112 cloned
113 }
114}