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