use serde::{de::DeserializeOwned, Deserialize, Serialize};
use wasm_bindgen::{JsCast, JsValue};
use super::transferable::serialize_to_worker_msg;
use crate::messages::post_message::PostMessage;
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub(crate) enum WorkerMsgType {
ReqFuture,
ReqStream,
ReqCallback,
ReqChannel,
Response,
}
pub(crate) struct WorkerMsg {
data: JsValue,
underlying_transferables: Option<js_sys::Array>,
msg_type: WorkerMsgType,
}
impl WorkerMsg {
pub fn new(msg_type: WorkerMsgType, data: impl Serialize) -> Self {
serialize_to_worker_msg(msg_type, data)
}
pub fn construct(
data: JsValue,
underlying_transferables: js_sys::Array,
msg_type: WorkerMsgType,
) -> Self {
Self {
data,
underlying_transferables: Some(underlying_transferables),
msg_type,
}
}
pub fn new_null(msg_type: WorkerMsgType) -> Self {
Self {
data: JsValue::NULL,
underlying_transferables: Some(js_sys::Array::new()),
msg_type,
}
}
pub fn is_null(&self) -> bool {
self.data.is_null()
}
pub fn message_type(&self) -> WorkerMsgType {
self.msg_type
}
pub fn post(self, worker: &impl PostMessage) {
let to_send = js_sys::Array::new();
to_send.push(
&serde_wasm_bindgen::to_value(&self.msg_type)
.expect("Failed to serialize message type."),
);
to_send.push(&self.data);
let underlying_transferables = self
.underlying_transferables
.expect("This WorkerMsg was decoded rather than prepared for sending, bug.");
if underlying_transferables.length() == 0 {
worker.post_message(&to_send);
} else {
worker.post_message_with_transfer(&to_send, &underlying_transferables);
}
}
pub fn decode(value: JsValue) -> Self {
let type_data_and_transferables = value.unchecked_into::<js_sys::Array>();
let msg_type = serde_wasm_bindgen::from_value(type_data_and_transferables.get(0))
.expect("Failed to deserialize message type.");
let data = type_data_and_transferables.get(1);
Self {
msg_type,
data,
underlying_transferables: None,
}
}
pub fn into_inner<T: DeserializeOwned>(self) -> T {
serde_wasm_bindgen::from_value(self.data).expect("Failed to deserialize message data.")
}
}