1use super::{JsValue, js_sys};
2
3pub trait Post: AsJs {
9 fn transferables(&self) -> js_sys::Array {
14 js_sys::Array::new()
15 }
16}
17
18pub trait PostExt {
22 fn post(&self, message: impl Post) -> Result<(), JsValue>;
31}
32
33impl PostExt for web_sys::MessagePort {
34 fn post(&self, message: impl Post) -> Result<(), JsValue> {
35 #![allow(clippy::needless_pass_by_value)]
39
40 self.post_message_with_transferable(&message.to_js()?, &message.transferables())
41 }
42}
43
44impl PostExt for web_sys::Worker {
45 fn post(&self, message: impl Post) -> Result<(), JsValue> {
46 #![allow(clippy::needless_pass_by_value)]
50
51 self.post_message_with_transfer(&message.to_js()?, &message.transferables())
52 }
53}
54
55#[derive(serde::Serialize)]
58pub struct Postable {
59 #[serde(with = "serde_wasm_bindgen::preserve")]
60 message: JsValue,
61 #[serde(with = "serde_wasm_bindgen::preserve")]
62 transfer: js_sys::Array,
63}
64
65impl Postable {
66 pub fn new(message: impl Post) -> Result<Self, JsValue> {
67 #![allow(clippy::needless_pass_by_value)]
71
72 Ok(Self {
73 message: message.to_js()?,
74 transfer: message.transferables(),
75 })
76 }
77}
78
79pub trait AsJs {
81 fn to_js(&self) -> Result<JsValue, JsValue>;
82 fn from_js(js_value: JsValue) -> Result<Self, JsValue>
83 where
84 Self: Sized;
85}
86
87impl<T: serde::Serialize + serde::de::DeserializeOwned> AsJs for T {
88 fn to_js(&self) -> Result<JsValue, JsValue> {
89 Ok(serde_wasm_bindgen::to_value(self)?)
90 }
91
92 fn from_js(value: JsValue) -> Result<Self, JsValue>
93 where
94 Self: Sized,
95 {
96 Ok(serde_wasm_bindgen::from_value(value)?)
97 }
98}
99
100impl Post for () {}
101impl Post for u8 {}
102impl Post for u16 {}
103impl Post for u32 {}
104impl Post for u64 {}
105impl Post for u128 {}
106impl Post for i8 {}
107impl Post for i16 {}
108impl Post for i32 {}
109impl Post for i64 {}
110impl Post for i128 {}
111impl Post for String {}
112
113impl<T: Post, E: Post> Post for Result<T, E>
114where
115 Result<T, E>: AsJs,
116{
117 fn transferables(&self) -> js_sys::Array {
118 match self {
119 Ok(x) => x.transferables(),
120 Err(e) => e.transferables(),
121 }
122 }
123}