Skip to main content

pax_message/
lib.rs

1pub mod http_api;
2pub mod reflection;
3
4//FUTURE: feature-flag, only for Web builds
5#[allow(unused_imports)]
6use wasm_bindgen::prelude::*;
7
8pub mod refcell_debug;
9pub use serde;
10
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13
14#[cfg_attr(debug_assertions, derive(Debug))]
15#[derive(Serialize)]
16/// Messages emitted by the runtime to create, update, delete, or configure native/chassis resources.
17pub enum NativeMessage {
18    TextCreate(AnyCreatePatch),
19    TextUpdate(TextPatch),
20    TextDelete(u32),
21    FrameCreate(AnyCreatePatch),
22    FrameUpdate(FramePatch),
23    FrameDelete(u32),
24    EventBlockerCreate(AnyCreatePatch),
25    EventBlockerUpdate(EventBlockerPatch),
26    EventBlockerDelete(u32),
27    CheckboxCreate(AnyCreatePatch),
28    CheckboxUpdate(CheckboxPatch),
29    CheckboxDelete(u32),
30    NativeImageCreate(AnyCreatePatch),
31    NativeImageUpdate(NativeImagePatch),
32    NativeImageDelete(u32),
33    YoutubeVideoCreate(AnyCreatePatch),
34    YoutubeVideoUpdate(YoutubeVideoPatch),
35    YoutubeVideoDelete(u32),
36    TextboxCreate(AnyCreatePatch),
37    TextboxUpdate(TextboxPatch),
38    TextboxDelete(u32),
39    SliderCreate(AnyCreatePatch),
40    SliderUpdate(SliderPatch),
41    SliderDelete(u32),
42    DropdownCreate(AnyCreatePatch),
43    DropdownUpdate(DropdownPatch),
44    DropdownDelete(u32),
45    RadioListCreate(AnyCreatePatch),
46    RadioListUpdate(RadioListPatch),
47    RadioListDelete(u32),
48    ButtonCreate(AnyCreatePatch),
49    ButtonUpdate(ButtonPatch),
50    ButtonDelete(u32),
51    PhotoPickerCreate(AnyCreatePatch),
52    PhotoPickerUpdate(PhotoPickerPatch),
53    PhotoPickerDelete(u32),
54    GlassSurfaceCreate(AnyCreatePatch),
55    GlassSurfaceUpdate(GlassSurfacePatch),
56    GlassSurfaceDelete(u32),
57    ScrollerCreate(AnyCreatePatch),
58    ScrollerUpdate(ScrollerPatch),
59    ScrollerDelete(u32),
60    ImageLoad(ImagePatch),
61    ShrinkLayersTo(u32),
62    NativeMaskUpdate(NativeMaskPatch),
63    Navigate(NavigationPatch),
64    SetCursor(SetCursorPatch),
65    Screenshot(ScreenshotPatch),
66}
67
68#[derive(Deserialize)]
69#[repr(C)]
70/// Events and data packets sent from the chassis back into the Pax runtime.
71pub enum NativeInterrupt {
72    ChassisResizeRequestCollection(Vec<ChassisResizeRequestArgs>),
73    TextMeasurementResponse(TextMeasurementResponseArgs),
74    SelectStart(SelectStartArgs),
75    Focus(FocusInterruptArgs),
76    Scroll(ScrollInterruptArgs),
77    TouchStart(TouchStartInterruptArgs),
78    TouchMove(TouchMoveInterruptArgs),
79    TouchEnd(TouchEndInterruptArgs),
80    TouchCancel(TouchCancelInterruptArgs),
81    KeyDown(KeyDownInterruptArgs),
82    KeyUp(KeyUpInterruptArgs),
83    KeyPress(KeyPressInterruptArgs),
84    Click(ClickInterruptArgs),
85    Tap(TapInterruptArgs),
86    DoubleClick(DoubleClickInterruptArgs),
87    MouseMove(MouseMoveInterruptArgs),
88    Wheel(WheelInterruptArgs),
89    MouseDown(MouseDownInterruptArgs),
90    MouseUp(MouseUpInterruptArgs),
91    ContextMenu(ContextMenuInterruptArgs),
92    Image(ImageLoadInterruptArgs),
93    AddedLayer(AddedLayerArgs),
94    TextInput(TextInputArgs),
95    FormCheckboxToggle(FormCheckboxToggleArgs),
96    FormDropdownChange(FormDropdownChangeArgs),
97    FormSliderChange(FormSliderChangeArgs),
98    FormRadioListChange(FormRadioListChangeArgs),
99    FormTextboxChange(FormTextboxChangeArgs),
100    FormTextboxInput(FormTextboxInputArgs),
101    FormButtonClick(FormButtonClickArgs),
102    PhotoPicker(PhotoPickerInterruptArgs),
103    // TODO: remove alias once all persisted/older web chassis payloads use `ScrollerPosition`.
104    #[serde(alias = "Scrollbar")]
105    ScrollerPosition(ScrollerPositionInterruptArgs),
106    BrowserConfig(BrowserConfigInterruptArgs),
107    RenderSurfaceUpdate(RenderSurfaceUpdateArgs),
108    ViewportResize(ViewportResizeArgs),
109    RouteChange(RouteChangeInterruptArgs),
110    VisualViewportUpdate(VisualViewportUpdateArgs),
111    Gyro(GyroInterruptArgs),
112    Accel(AccelInterruptArgs),
113    DropFile(DropFileArgs),
114    Screenshot(ImageLoadInterruptArgs),
115}
116
117#[derive(Deserialize)]
118#[repr(C)]
119/// Chassis response containing measured native control bounds.
120pub struct ChassisResizeRequestArgs {
121    pub id: u32,
122    pub width: f64,
123    pub height: f64,
124}
125
126#[derive(Deserialize)]
127#[repr(C)]
128/// Chassis response to an engine-authored native text measurement request.
129pub struct TextMeasurementResponseArgs {
130    pub id: u32,
131    pub generation: u64,
132    pub width: f64,
133    pub height: f64,
134}
135
136#[derive(Deserialize)]
137#[repr(C)]
138/// Checkbox state-change interrupt payload.
139pub struct FormCheckboxToggleArgs {
140    pub state: bool,
141    pub id: u32,
142}
143
144#[derive(Deserialize)]
145#[repr(C)]
146/// Focus interrupt marker payload.
147pub struct FocusInterruptArgs {}
148
149#[derive(Deserialize)]
150#[repr(C)]
151/// Selection-start interrupt marker payload.
152pub struct SelectStartArgs {}
153
154#[derive(Deserialize)]
155#[repr(C)]
156/// Textbox committed-value change payload.
157pub struct FormTextboxChangeArgs {
158    pub text: String,
159    pub id: u32,
160}
161
162#[derive(Deserialize)]
163#[repr(C)]
164/// Dropdown selection-change payload.
165pub struct FormDropdownChangeArgs {
166    pub id: u32,
167    pub selected_id: u32,
168}
169
170#[derive(Deserialize)]
171#[repr(C)]
172/// Slider value-change payload.
173pub struct FormSliderChangeArgs {
174    pub id: u32,
175    pub value: f64,
176}
177
178#[derive(Deserialize)]
179#[repr(C)]
180/// Radio-list selection-change payload.
181pub struct FormRadioListChangeArgs {
182    pub id: u32,
183    pub selected_id: u32,
184}
185
186#[derive(Deserialize)]
187#[repr(C)]
188/// Raw text input payload delivered by a native text control.
189pub struct TextInputArgs {
190    pub text: String,
191    pub id: u32,
192}
193
194#[derive(Deserialize)]
195#[repr(C)]
196/// Textbox in-progress input payload.
197pub struct FormTextboxInputArgs {
198    pub text: String,
199    pub id: u32,
200}
201
202#[derive(Deserialize)]
203#[repr(C)]
204/// Native button click payload.
205pub struct FormButtonClickArgs {
206    pub id: u32,
207}
208
209#[derive(Deserialize, Clone)]
210#[repr(C)]
211/// Selected image metadata and optional copied bytes from a native photo picker.
212pub struct PhotoPickerAssetArgs {
213    pub temp_id: String,
214    pub file_name: Option<String>,
215    pub mime_type: String,
216    pub byte_size: u64,
217    pub width: Option<u32>,
218    pub height: Option<u32>,
219    pub source_kind: String,
220    pub handle: Option<String>,
221    #[serde(default)]
222    pub data: Vec<u8>,
223}
224
225#[derive(Deserialize, Clone)]
226#[repr(C)]
227/// Native photo picker completion payload.
228pub struct PhotoPickerInterruptArgs {
229    pub id: u32,
230    pub request_id: u64,
231    pub status: String,
232    pub message: Option<String>,
233    #[serde(default)]
234    pub photos: Vec<PhotoPickerAssetArgs>,
235}
236
237#[derive(Deserialize)]
238#[repr(C)]
239/// Single-touch tap payload normalized to window coordinates.
240pub struct TapInterruptArgs {
241    pub x: f64,
242    pub y: f64,
243}
244
245#[derive(Deserialize)]
246#[repr(C)]
247/// Location-targeted scroll delta payload.
248pub struct ScrollInterruptArgs {
249    pub x: f64,
250    pub y: f64,
251    pub delta_x: f64,
252    pub delta_y: f64,
253}
254
255#[derive(Deserialize)]
256#[repr(C)]
257/// Native scroller position payload, including optional presentation offsets.
258pub struct ScrollerPositionInterruptArgs {
259    pub id: u32,
260    pub scroll_x: f64,
261    pub scroll_y: f64,
262    pub presentation_scroll_x: Option<f64>,
263    pub presentation_scroll_y: Option<f64>,
264}
265
266#[derive(Deserialize)]
267#[repr(C)]
268/// Browser capability flags discovered by the web chassis.
269pub struct BrowserConfigInterruptArgs {
270    pub allow_scroller_vector_layers: bool,
271    pub allow_nested_scroller_vector_layers: bool,
272}
273
274#[derive(Deserialize)]
275#[repr(C)]
276/// Browser notification that a retained render surface must be reconfigured.
277pub struct RenderSurfaceUpdateArgs {
278    #[serde(default)]
279    pub layer_id: Option<u32>,
280}
281
282#[derive(Deserialize)]
283#[repr(C)]
284/// Layout viewport resize payload for the root app surface.
285pub struct ViewportResizeArgs {
286    pub width: f64,
287    pub height: f64,
288}
289
290#[derive(Deserialize)]
291#[repr(C)]
292/// Canonical route-location payload pushed from chassis state into the runtime.
293pub struct RouteChangeInterruptArgs {
294    pub path_segments: Vec<String>,
295    pub query: HashMap<String, Vec<String>>,
296    pub fragment: Option<String>,
297}
298
299#[derive(Deserialize)]
300#[repr(C)]
301/// Browser visual viewport payload for page-scroll-backed root scrollers.
302pub struct VisualViewportUpdateArgs {
303    pub width: f64,
304    pub height: f64,
305    pub offset_x: f64,
306    pub offset_y: f64,
307    pub page_scroll_x: f64,
308    pub page_scroll_y: f64,
309}
310
311#[derive(Deserialize)]
312#[repr(C)]
313/// Device orientation payload, in degrees.
314pub struct GyroInterruptArgs {
315    pub x: f64,
316    pub y: f64,
317    pub z: f64,
318}
319
320#[derive(Deserialize)]
321#[repr(C)]
322/// Device acceleration payload, in meters per second squared.
323pub struct AccelInterruptArgs {
324    pub x: f64,
325    pub y: f64,
326    pub z: f64,
327}
328
329#[derive(Deserialize)]
330#[repr(C)]
331/// One touch point in a multi-touch interrupt.
332pub struct TouchMessage {
333    pub x: f64,
334    pub y: f64,
335    pub identifier: i64,
336    pub delta_x: f64,
337    pub delta_y: f64,
338}
339
340#[derive(Deserialize)]
341#[repr(C)]
342/// Touch-start interrupt payload.
343pub struct TouchStartInterruptArgs {
344    pub touches: Vec<TouchMessage>,
345}
346
347#[derive(Deserialize)]
348#[repr(C)]
349/// Touch-move interrupt payload.
350pub struct TouchMoveInterruptArgs {
351    pub touches: Vec<TouchMessage>,
352}
353
354#[derive(Deserialize)]
355#[repr(C)]
356/// Touch-end interrupt payload.
357pub struct TouchEndInterruptArgs {
358    pub touches: Vec<TouchMessage>,
359}
360
361#[derive(Deserialize)]
362#[repr(C)]
363/// Touch-cancel interrupt payload.
364pub struct TouchCancelInterruptArgs {
365    pub touches: Vec<TouchMessage>,
366}
367
368#[derive(Deserialize)]
369#[repr(C)]
370/// File-drop interrupt payload.
371pub struct DropFileArgs {
372    pub x: f64,
373    pub y: f64,
374    pub name: String,
375    pub mime_type: String,
376    pub size: u64,
377}
378
379#[derive(Deserialize, Clone)]
380#[repr(C)]
381/// Normalized mouse button identifier.
382pub enum MouseButtonMessage {
383    Left,
384    Right,
385    Middle,
386    Unknown,
387}
388
389#[derive(Deserialize)]
390#[repr(C)]
391/// Normalized keyboard modifier identifier.
392pub enum ModifierKeyMessage {
393    Shift,
394    Control,
395    Alt,
396    Command,
397}
398
399#[derive(Deserialize)]
400#[repr(C)]
401/// Key-down interrupt payload.
402pub struct KeyDownInterruptArgs {
403    pub key: String,
404    pub modifiers: Vec<ModifierKeyMessage>,
405    pub is_repeat: bool,
406}
407
408#[derive(Deserialize)]
409#[repr(C)]
410/// Key-up interrupt payload.
411pub struct KeyUpInterruptArgs {
412    pub key: String,
413    pub modifiers: Vec<ModifierKeyMessage>,
414    pub is_repeat: bool,
415}
416
417#[derive(Deserialize)]
418#[repr(C)]
419/// Key-press interrupt payload.
420pub struct KeyPressInterruptArgs {
421    pub key: String,
422    pub modifiers: Vec<ModifierKeyMessage>,
423    pub is_repeat: bool,
424}
425
426#[derive(Deserialize)]
427#[repr(C)]
428/// Click interrupt payload.
429pub struct ClickInterruptArgs {
430    pub x: f64,
431    pub y: f64,
432    pub button: MouseButtonMessage,
433    pub modifiers: Vec<ModifierKeyMessage>,
434}
435
436#[derive(Deserialize)]
437#[repr(C)]
438/// Double-click interrupt payload.
439pub struct DoubleClickInterruptArgs {
440    pub x: f64,
441    pub y: f64,
442    pub button: MouseButtonMessage,
443    pub modifiers: Vec<ModifierKeyMessage>,
444}
445
446#[derive(Deserialize)]
447#[repr(C)]
448/// Mouse-move interrupt payload.
449pub struct MouseMoveInterruptArgs {
450    pub x: f64,
451    pub y: f64,
452    pub button: MouseButtonMessage,
453    pub modifiers: Vec<ModifierKeyMessage>,
454}
455
456#[derive(Deserialize)]
457#[repr(C)]
458/// Wheel interrupt payload.
459pub struct WheelInterruptArgs {
460    pub x: f64,
461    pub y: f64,
462    pub delta_x: f64,
463    pub delta_y: f64,
464    pub modifiers: Vec<ModifierKeyMessage>,
465}
466
467#[derive(Deserialize)]
468#[repr(C)]
469/// Mouse-down interrupt payload.
470pub struct MouseDownInterruptArgs {
471    pub x: f64,
472    pub y: f64,
473    pub button: MouseButtonMessage,
474    pub modifiers: Vec<ModifierKeyMessage>,
475}
476
477#[derive(Deserialize)]
478#[repr(C)]
479/// Mouse-up interrupt payload.
480pub struct MouseUpInterruptArgs {
481    pub x: f64,
482    pub y: f64,
483    pub button: MouseButtonMessage,
484    pub modifiers: Vec<ModifierKeyMessage>,
485}
486
487#[derive(Deserialize)]
488#[repr(C)]
489/// Mouse-over interrupt payload.
490pub struct MouseOverInterruptArgs {
491    pub x: f64,
492    pub y: f64,
493    pub button: MouseButtonMessage,
494    pub modifiers: Vec<ModifierKeyMessage>,
495}
496
497#[derive(Deserialize)]
498#[repr(C)]
499/// Mouse-out interrupt payload.
500pub struct MouseOutInterruptArgs {
501    pub x: f64,
502    pub y: f64,
503    pub button: MouseButtonMessage,
504    pub modifiers: Vec<ModifierKeyMessage>,
505}
506
507#[derive(Deserialize)]
508#[repr(C)]
509/// Context-menu interrupt payload.
510pub struct ContextMenuInterruptArgs {
511    pub x: f64,
512    pub y: f64,
513    pub button: MouseButtonMessage,
514    pub modifiers: Vec<ModifierKeyMessage>,
515}
516
517#[derive(Deserialize)]
518#[repr(C)]
519/// Image-load response, either by pointer or copied metadata.
520pub enum ImageLoadInterruptArgs {
521    Reference(ImagePointerArgs),
522    Data(ImageDataArgs),
523}
524#[derive(Deserialize)]
525#[repr(C)]
526/// Image-load payload carrying a pointer to chassis-owned image bytes.
527pub struct ImagePointerArgs {
528    pub id: u32,
529    pub path: String,
530    pub image_data: u64,
531    pub image_data_length: usize,
532    pub width: usize,
533    pub height: usize,
534}
535
536#[derive(Deserialize)]
537#[repr(C)]
538/// Image-load payload carrying image metadata without a byte pointer.
539pub struct ImageDataArgs {
540    pub id: u32,
541    pub path: String,
542    pub width: usize,
543    pub height: usize,
544}
545
546#[repr(C)]
547/// Raw FFI buffer containing serialized interrupts.
548pub struct InterruptBuffer {
549    pub data_ptr: *const u8,
550    pub length: u64,
551}
552
553#[repr(C)]
554/// Raw FFI buffer containing serialized native messages.
555pub struct NativeMessageQueue {
556    pub data_ptr: *mut [u8],
557    pub length: u64,
558}
559
560#[derive(Serialize)]
561/// Serializable batch of native messages emitted for one runtime tick.
562pub struct MessageQueue {
563    pub messages: Vec<NativeMessage>,
564}
565
566#[derive(Deserialize)]
567#[repr(C)]
568/// Chassis acknowledgement that render layers were added.
569pub struct AddedLayerArgs {
570    pub num_layers_added: u32,
571    #[serde(default)]
572    pub layer_id: Option<u32>,
573}
574
575#[cfg_attr(debug_assertions, derive(Debug))]
576#[derive(Default, Serialize)]
577#[repr(C)]
578/// Create/update patch for a native frame host.
579pub struct FramePatch {
580    pub id: u32,
581    #[serde(skip_serializing_if = "Option::is_none")]
582    pub parent_frame: Option<Option<u32>>,
583    #[serde(skip_serializing_if = "Option::is_none")]
584    pub z_index: Option<i32>,
585    pub clip_content: Option<bool>,
586    pub corner_radius: Option<f64>,
587    pub size_x: Option<f64>,
588    pub size_y: Option<f64>,
589    pub transform: Option<Vec<f64>>,
590    pub clip_path: Option<String>,
591    pub opacity: Option<f64>,
592    pub presented_bounds: Option<[f64; 4]>,
593    pub presented_clip_bounds: Option<[f64; 4]>,
594}
595
596#[cfg_attr(debug_assertions, derive(Debug))]
597#[derive(Default, Serialize, Clone, PartialEq)]
598#[repr(C)]
599/// Apple-specific native liquid-glass effect payload.
600pub struct AppleLiquidGlassPatch {
601    pub group_id: u32,
602    pub spacing: f64,
603    pub interactive: bool,
604    #[serde(skip_serializing_if = "Option::is_none")]
605    pub tint: Option<ColorMessage>,
606    pub variant: String,
607}
608
609#[cfg_attr(debug_assertions, derive(Debug))]
610#[derive(Default, Serialize)]
611#[repr(C)]
612/// Create/update patch for a materialized native liquid-glass surface.
613pub struct GlassSurfacePatch {
614    pub id: u32,
615    #[serde(skip_serializing_if = "Option::is_none")]
616    pub parent_frame: Option<Option<u32>>,
617    #[serde(skip_serializing_if = "Option::is_none")]
618    pub z_index: Option<i32>,
619    pub transform: Option<Vec<f64>>,
620    pub size_x: Option<f64>,
621    pub size_y: Option<f64>,
622    pub opacity: Option<f64>,
623    pub corner_radius: Option<f64>,
624    pub liquid_glass: Option<AppleLiquidGlassPatch>,
625}
626
627#[cfg_attr(debug_assertions, derive(Debug))]
628#[derive(Default, Serialize, Clone)]
629#[repr(C)]
630/// One vector coverage path entry for a native occlusion mask.
631pub struct MaskPathPatch {
632    pub path: String,
633    pub clips: Vec<String>,
634    pub opacity: Option<f64>,
635}
636
637impl PartialEq for MaskPathPatch {
638    fn eq(&self, other: &Self) -> bool {
639        self.path == other.path
640            && self.clips == other.clips
641            && self.opacity.map(f64::to_bits) == other.opacity.map(f64::to_bits)
642    }
643}
644
645impl Eq for MaskPathPatch {}
646
647impl std::hash::Hash for MaskPathPatch {
648    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
649        self.path.hash(state);
650        self.clips.hash(state);
651        self.opacity.map(f64::to_bits).hash(state);
652    }
653}
654
655#[cfg_attr(debug_assertions, derive(Debug))]
656#[derive(Default, Serialize, Clone, PartialEq)]
657#[repr(C)]
658/// Create/update patch for a native occlusion mask surface.
659pub struct NativeMaskPatch {
660    pub id: u32,
661    pub size_x: f64,
662    pub size_y: f64,
663    pub entries: Vec<MaskPathPatch>,
664}
665
666#[cfg_attr(debug_assertions, derive(Debug))]
667#[derive(Default, Serialize)]
668#[repr(C)]
669/// Create/update patch for a native hit-test blocker with an optional solid background.
670pub struct EventBlockerPatch {
671    pub id: u32,
672    #[serde(skip_serializing_if = "Option::is_none")]
673    pub parent_frame: Option<Option<u32>>,
674    #[serde(skip_serializing_if = "Option::is_none")]
675    pub z_index: Option<i32>,
676    pub size_x: Option<f64>,
677    pub size_y: Option<f64>,
678    pub transform: Option<Vec<f64>>,
679    pub opacity: Option<f64>,
680    pub background: Option<ColorMessage>,
681}
682
683#[cfg_attr(debug_assertions, derive(Debug))]
684#[derive(Default, Serialize, Clone)]
685#[repr(C)]
686/// Create/update patch for a native checkbox.
687pub struct CheckboxPatch {
688    pub id: u32,
689    #[serde(skip_serializing_if = "Option::is_none")]
690    pub parent_frame: Option<Option<u32>>,
691    #[serde(skip_serializing_if = "Option::is_none")]
692    pub z_index: Option<i32>,
693    pub background: Option<ColorMessage>,
694    pub background_checked: Option<ColorMessage>,
695    pub outline_color: Option<ColorMessage>,
696    pub outline_width: Option<f64>,
697    pub corner_radius: Option<f64>,
698    pub transform: Option<Vec<f64>>,
699    pub size_x: Option<f64>,
700    pub size_y: Option<f64>,
701    pub opacity: Option<f64>,
702    pub checked: Option<bool>,
703    #[serde(skip_serializing_if = "Option::is_none")]
704    pub liquid_glass: Option<Option<AppleLiquidGlassPatch>>,
705}
706
707#[cfg_attr(debug_assertions, derive(Debug))]
708#[derive(Default, Serialize, Clone)]
709#[repr(C)]
710/// Create/update patch for a native image element.
711pub struct NativeImagePatch {
712    pub id: u32,
713    #[serde(skip_serializing_if = "Option::is_none")]
714    pub parent_frame: Option<Option<u32>>,
715    #[serde(skip_serializing_if = "Option::is_none")]
716    pub z_index: Option<i32>,
717    pub transform: Option<Vec<f64>>,
718    pub size_x: Option<f64>,
719    pub size_y: Option<f64>,
720    pub opacity: Option<f64>,
721    pub url: Option<String>,
722    pub fit: Option<String>,
723}
724
725#[cfg_attr(debug_assertions, derive(Debug))]
726#[derive(Default, Serialize, Clone)]
727#[repr(C)]
728/// Create/update patch for an embedded YouTube video.
729pub struct YoutubeVideoPatch {
730    pub id: u32,
731    #[serde(skip_serializing_if = "Option::is_none")]
732    pub parent_frame: Option<Option<u32>>,
733    #[serde(skip_serializing_if = "Option::is_none")]
734    pub z_index: Option<i32>,
735    pub transform: Option<Vec<f64>>,
736    pub size_x: Option<f64>,
737    pub size_y: Option<f64>,
738    pub opacity: Option<f64>,
739    pub url: Option<String>,
740}
741
742#[cfg_attr(debug_assertions, derive(Debug))]
743#[derive(Default, Serialize, Clone)]
744#[repr(C)]
745/// Create/update patch for a native dropdown/select element.
746pub struct DropdownPatch {
747    pub id: u32,
748    #[serde(skip_serializing_if = "Option::is_none")]
749    pub parent_frame: Option<Option<u32>>,
750    #[serde(skip_serializing_if = "Option::is_none")]
751    pub z_index: Option<i32>,
752    pub selected_id: Option<u32>,
753    pub options: Option<Vec<String>>,
754    pub transform: Option<Vec<f64>>,
755    pub size_x: Option<f64>,
756    pub size_y: Option<f64>,
757    pub opacity: Option<f64>,
758    pub background: Option<ColorMessage>,
759    pub stroke_color: Option<ColorMessage>,
760    pub stroke_width: Option<f64>,
761    pub corner_radius: Option<f64>,
762    pub style: Option<TextStyleMessage>,
763    #[serde(skip_serializing_if = "Option::is_none")]
764    pub liquid_glass: Option<Option<AppleLiquidGlassPatch>>,
765}
766
767#[cfg_attr(debug_assertions, derive(Debug))]
768#[derive(Default, Serialize, Clone)]
769#[repr(C)]
770/// Create/update patch for a native radio list.
771pub struct RadioListPatch {
772    pub id: u32,
773    #[serde(skip_serializing_if = "Option::is_none")]
774    pub parent_frame: Option<Option<u32>>,
775    #[serde(skip_serializing_if = "Option::is_none")]
776    pub z_index: Option<i32>,
777    pub selected_id: Option<u32>,
778    pub options: Option<Vec<String>>,
779    pub style: Option<TextStyleMessage>,
780    pub background_checked: Option<ColorMessage>,
781    pub outline_color: Option<ColorMessage>,
782    pub outline_width: Option<f64>,
783    pub background: Option<ColorMessage>,
784    pub transform: Option<Vec<f64>>,
785    pub size_x: Option<f64>,
786    pub size_y: Option<f64>,
787    pub opacity: Option<f64>,
788    #[serde(skip_serializing_if = "Option::is_none")]
789    pub liquid_glass: Option<Option<AppleLiquidGlassPatch>>,
790}
791
792#[cfg_attr(debug_assertions, derive(Debug))]
793#[derive(Default, Serialize, Clone)]
794#[repr(C)]
795/// Create/update patch for a native slider.
796pub struct SliderPatch {
797    pub id: u32,
798    #[serde(skip_serializing_if = "Option::is_none")]
799    pub parent_frame: Option<Option<u32>>,
800    #[serde(skip_serializing_if = "Option::is_none")]
801    pub z_index: Option<i32>,
802    pub value: Option<f64>,
803    pub step: Option<f64>,
804    pub min: Option<f64>,
805    pub max: Option<f64>,
806    pub transform: Option<Vec<f64>>,
807    pub size_x: Option<f64>,
808    pub size_y: Option<f64>,
809    pub opacity: Option<f64>,
810    pub accent: Option<ColorMessage>,
811    pub background: Option<ColorMessage>,
812    pub corner_radius: Option<f64>,
813    #[serde(skip_serializing_if = "Option::is_none")]
814    pub liquid_glass: Option<Option<AppleLiquidGlassPatch>>,
815}
816
817#[cfg_attr(debug_assertions, derive(Debug))]
818#[derive(Default, Serialize, Clone)]
819#[repr(C)]
820/// Create/update patch for a native textbox.
821pub struct TextboxPatch {
822    pub id: u32,
823    #[serde(skip_serializing_if = "Option::is_none")]
824    pub parent_frame: Option<Option<u32>>,
825    #[serde(skip_serializing_if = "Option::is_none")]
826    pub z_index: Option<i32>,
827    pub transform: Option<Vec<f64>>,
828    pub size_x: Option<f64>,
829    pub size_y: Option<f64>,
830    pub opacity: Option<f64>,
831    pub text: Option<String>,
832    pub background: Option<ColorMessage>,
833    pub stroke_color: Option<ColorMessage>,
834    pub stroke_width: Option<f64>,
835    pub corner_radius: Option<f64>,
836    pub style: Option<TextStyleMessage>,
837    pub focus_on_mount: Option<bool>,
838    pub placeholder: Option<String>,
839    pub outline_color: Option<ColorMessage>,
840    pub outline_width: Option<f64>,
841    pub is_text_area: Option<bool>,
842    #[serde(skip_serializing_if = "Option::is_none")]
843    pub liquid_glass: Option<Option<AppleLiquidGlassPatch>>,
844}
845
846#[cfg_attr(debug_assertions, derive(Debug))]
847#[derive(Default, Serialize)]
848#[repr(C)]
849/// Create/update patch for a native button.
850pub struct ButtonPatch {
851    pub id: u32,
852    #[serde(skip_serializing_if = "Option::is_none")]
853    pub parent_frame: Option<Option<u32>>,
854    #[serde(skip_serializing_if = "Option::is_none")]
855    pub z_index: Option<i32>,
856    pub hover_color: Option<ColorMessage>,
857    pub outline_stroke_color: Option<ColorMessage>,
858    pub outline_stroke_width: Option<f64>,
859    pub corner_radius: Option<f64>,
860    pub transform: Option<Vec<f64>>,
861    pub size_x: Option<f64>,
862    pub size_y: Option<f64>,
863    pub opacity: Option<f64>,
864    pub content: Option<String>,
865    pub color: Option<ColorMessage>,
866    pub style: Option<TextStyleMessage>,
867    #[serde(skip_serializing_if = "Option::is_none")]
868    pub liquid_glass: Option<Option<AppleLiquidGlassPatch>>,
869}
870
871#[cfg_attr(debug_assertions, derive(Debug))]
872#[derive(Default, Serialize, Clone)]
873#[repr(C)]
874/// Create/update patch for a transparent native photo picker hit target.
875pub struct PhotoPickerPatch {
876    pub id: u32,
877    #[serde(skip_serializing_if = "Option::is_none")]
878    pub parent_frame: Option<Option<u32>>,
879    #[serde(skip_serializing_if = "Option::is_none")]
880    pub z_index: Option<i32>,
881    pub transform: Option<Vec<f64>>,
882    pub size_x: Option<f64>,
883    pub size_y: Option<f64>,
884    pub opacity: Option<f64>,
885    pub trigger: Option<u64>,
886    pub source: Option<String>,
887    pub allow_multiple: Option<bool>,
888    pub accept: Option<String>,
889    pub include_bytes: Option<bool>,
890    pub max_bytes_per_photo: Option<u64>,
891}
892
893#[derive(Default, Serialize)]
894#[repr(C)]
895/// Style payload shared by checkbox-like controls.
896pub struct CheckboxStyleMessage {
897    //pub fill: Option<ColorMessage>,
898}
899
900#[cfg_attr(debug_assertions, derive(Debug))]
901#[derive(Default, Serialize)]
902#[repr(C)]
903/// Request for the chassis to navigate to a URL.
904pub struct NavigationPatch {
905    pub url: String,
906    pub target: String,
907}
908
909#[cfg_attr(debug_assertions, derive(Debug))]
910#[derive(Default, Serialize)]
911#[repr(C)]
912/// Request for the chassis to update cursor style.
913pub struct SetCursorPatch {
914    pub cursor: String,
915}
916
917#[cfg_attr(debug_assertions, derive(Debug))]
918#[derive(Default, Serialize, Clone)]
919#[repr(C)]
920/// Create/update patch for native or browser-managed text.
921pub struct TextPatch {
922    pub id: u32,
923    #[serde(skip_serializing_if = "Option::is_none")]
924    pub parent_frame: Option<Option<u32>>,
925    #[serde(skip_serializing_if = "Option::is_none")]
926    pub z_index: Option<i32>,
927    pub content: Option<String>,
928    pub editable: Option<bool>,
929    pub selectable: Option<bool>,
930    pub clip: Option<bool>,
931    pub markdown: Option<bool>,
932    pub wrap: Option<bool>,
933    pub transform: Option<Vec<f64>>,
934    pub size_x: Option<f64>,
935    pub size_y: Option<f64>,
936    pub opacity: Option<f64>,
937    pub style: Option<TextStyleMessage>,
938    pub style_link: Option<TextStyleMessage>,
939    #[serde(skip_serializing_if = "Option::is_none")]
940    pub measure_generation: Option<u64>,
941}
942
943#[cfg_attr(debug_assertions, derive(Debug))]
944#[derive(Default, Serialize, Clone, PartialEq)]
945#[repr(C)]
946/// Serializable text style payload shared with chassis text renderers.
947pub struct TextStyleMessage {
948    pub font: Option<FontPatch>,
949    pub font_size: Option<f64>,
950    pub fill: Option<ColorMessage>,
951    pub underline: Option<bool>,
952    pub align_multiline: Option<TextAlignHorizontalMessage>,
953    pub align_vertical: Option<TextAlignVerticalMessage>,
954    pub align_horizontal: Option<TextAlignHorizontalMessage>,
955}
956
957#[cfg_attr(debug_assertions, derive(Debug))]
958#[derive(Default, Serialize)]
959#[repr(C)]
960/// Image-load request sent to the chassis.
961pub struct ImagePatch {
962    pub id: u32,
963    pub path: Option<String>,
964}
965
966#[cfg_attr(debug_assertions, derive(Debug))]
967#[derive(Serialize, Clone, PartialEq)]
968#[repr(C)]
969/// Serializable color payload for native/chassis messages.
970pub enum ColorMessage {
971    Rgba([f64; 4]),
972    Rgb([f64; 3]),
973}
974
975impl Default for ColorMessage {
976    fn default() -> Self {
977        ColorMessage::Rgba([1.0, 0.5, 0.0, 1.0])
978    }
979}
980
981#[cfg_attr(debug_assertions, derive(Debug))]
982#[derive(Default, Serialize, Clone, PartialEq)]
983#[repr(C)]
984/// Serializable horizontal text alignment.
985pub enum TextAlignHorizontalMessage {
986    #[default]
987    Left,
988    Center,
989    Right,
990}
991
992#[cfg_attr(debug_assertions, derive(Debug))]
993#[derive(Default, Serialize, Clone, PartialEq)]
994#[repr(C)]
995/// Serializable vertical text alignment.
996pub enum TextAlignVerticalMessage {
997    #[default]
998    Top,
999    Center,
1000    Bottom,
1001}
1002
1003#[derive(Serialize)]
1004#[repr(C)]
1005/// Serializable style payload for link text.
1006pub struct LinkStyleMessage {
1007    pub font: Option<FontPatch>,
1008    pub fill: Option<ColorMessage>,
1009    pub underline: Option<bool>,
1010    pub size: Option<f64>,
1011}
1012
1013#[cfg_attr(debug_assertions, derive(Debug))]
1014#[derive(Default, Serialize)]
1015#[repr(C)]
1016/// Create/update patch for a native/browser-owned scroller.
1017pub struct ScrollerPatch {
1018    pub id: u32,
1019    #[serde(skip_serializing_if = "Option::is_none")]
1020    pub parent_frame: Option<Option<u32>>,
1021    #[serde(skip_serializing_if = "Option::is_none")]
1022    pub z_index: Option<i32>,
1023    pub transform: Option<Vec<f64>>,
1024    pub size_x: Option<f64>,
1025    pub size_y: Option<f64>,
1026    pub opacity: Option<f64>,
1027    pub clip_content: Option<bool>,
1028    pub corner_radius: Option<f64>,
1029    pub size_inner_pane_x: Option<f64>,
1030    pub size_inner_pane_y: Option<f64>,
1031    pub snap_points_x: Option<Vec<f64>>,
1032    pub snap_points_y: Option<Vec<f64>>,
1033    pub scroll_x: Option<f64>,
1034    pub scroll_y: Option<f64>,
1035    #[serde(skip_serializing_if = "Option::is_none")]
1036    pub presentation_scroll_x: Option<f64>,
1037    #[serde(skip_serializing_if = "Option::is_none")]
1038    pub presentation_scroll_y: Option<f64>,
1039    pub scroll_enabled_x: Option<bool>,
1040    pub scroll_enabled_y: Option<bool>,
1041    pub content_layer_id: Option<u32>,
1042    pub presented_bounds: Option<[f64; 4]>,
1043    pub presented_clip_bounds: Option<[f64; 4]>,
1044    pub subtree_depth: u32,
1045}
1046
1047#[cfg_attr(debug_assertions, derive(Debug))]
1048#[derive(Serialize)]
1049#[repr(C)]
1050/// Common creation payload shared by native element families.
1051pub struct AnyCreatePatch {
1052    pub id: u32,
1053    pub parent_frame: Option<u32>,
1054    pub render_layer_id: u32,
1055}
1056
1057// Possible approach to heterogeneous rich text:
1058// #[repr(C)]
1059// pub struct TextCommand {
1060//     pub set_font: Option<String>,
1061//     pub set_weight: Option<String>,
1062//     pub set_fill_color: Option<String>,
1063//     pub set_stroke_color: Option<String>,
1064//     pub set_decoration: Option<String>,
1065// }
1066
1067#[cfg_attr(debug_assertions, derive(Debug))]
1068#[derive(Serialize, Clone, PartialEq)]
1069#[repr(C)]
1070/// Serializable font selection payload.
1071pub enum FontPatch {
1072    System(SystemFontMessage),
1073    Web(WebFontMessage),
1074    Local(LocalFontMessage),
1075}
1076
1077impl Default for FontPatch {
1078    fn default() -> Self {
1079        Self::System(SystemFontMessage::default())
1080    }
1081}
1082
1083#[cfg_attr(debug_assertions, derive(Debug))]
1084#[derive(Serialize, Clone, PartialEq)]
1085#[repr(C)]
1086/// System font family payload.
1087pub struct SystemFontMessage {
1088    pub family: Option<String>,
1089    pub style: Option<FontStyleMessage>,
1090    pub weight: Option<FontWeightMessage>,
1091}
1092
1093impl Default for SystemFontMessage {
1094    fn default() -> Self {
1095        Self {
1096            family: Some("Brush Script MT".to_string()),
1097            style: Some(FontStyleMessage::Normal),
1098            weight: Some(FontWeightMessage::Normal),
1099        }
1100    }
1101}
1102
1103#[cfg_attr(debug_assertions, derive(Debug))]
1104#[derive(Serialize, Clone, PartialEq)]
1105#[repr(C)]
1106/// Web font payload, including family and source URL.
1107pub struct WebFontMessage {
1108    pub family: Option<String>,
1109    pub url: Option<String>,
1110    pub style: Option<FontStyleMessage>,
1111    pub weight: Option<FontWeightMessage>,
1112}
1113
1114#[cfg_attr(debug_assertions, derive(Debug))]
1115#[derive(Serialize, Clone, PartialEq)]
1116#[repr(C)]
1117/// Local bundled font payload.
1118pub struct LocalFontMessage {
1119    pub family: Option<String>,
1120    pub path: Option<String>,
1121    pub style: Option<FontStyleMessage>,
1122    pub weight: Option<FontWeightMessage>,
1123}
1124
1125#[cfg_attr(debug_assertions, derive(Debug))]
1126#[derive(Clone, Serialize, PartialEq)]
1127#[repr(C)]
1128/// Serializable font-style value.
1129pub enum FontStyleMessage {
1130    Normal,
1131    Italic,
1132    Oblique,
1133}
1134
1135#[cfg_attr(debug_assertions, derive(Debug))]
1136#[derive(Clone, Serialize, PartialEq)]
1137#[repr(C)]
1138/// Serializable font-weight value.
1139pub enum FontWeightMessage {
1140    Thin,
1141    ExtraLight,
1142    Light,
1143    Normal,
1144    Medium,
1145    SemiBold,
1146    Bold,
1147    ExtraBold,
1148    Black,
1149}
1150
1151#[cfg_attr(debug_assertions, derive(Debug))]
1152#[derive(Default, Serialize)]
1153#[repr(C)]
1154/// Request to capture a screenshot from the chassis.
1155pub struct ScreenshotPatch {
1156    pub id: u32,
1157    #[serde(skip_serializing_if = "Option::is_none")]
1158    pub scale: Option<f64>,
1159}
1160
1161#[derive(Serialize, Deserialize)]
1162/// Completed screenshot bytes returned by the chassis.
1163pub struct ScreenshotData {
1164    pub id: u32,
1165    pub data: Vec<u8>,
1166    pub width: usize,
1167    pub height: usize,
1168}
1169
1170#[derive(Serialize, Deserialize)]
1171/// Completed screenshot bytes for one physical surface within a logical canvas layer.
1172pub struct LayerSurfaceScreenshotData {
1173    pub id: u32,
1174    pub key: String,
1175    pub data: Vec<u8>,
1176    pub width: usize,
1177    pub height: usize,
1178    pub origin_x: f32,
1179    pub origin_y: f32,
1180    pub logical_width: f32,
1181    pub logical_height: f32,
1182}