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