1use std::rc::Rc;
2use wasm_bindgen::JsValue;
3
4#[derive(Clone)]
12pub enum Port {
13 Worker(Rc<web_sys::Worker>),
14 DedicatedWorkerGlobalScope(Rc<web_sys::DedicatedWorkerGlobalScope>),
15 MessagePort(Rc<web_sys::MessagePort>),
16}
17
18impl Port {
19 pub fn post_message(&self, message: &JsValue, transfer: &JsValue) -> Result<(), JsValue> {
21 match self {
22 Port::Worker(worker) => worker.post_message_with_transfer(message, transfer),
23 Port::DedicatedWorkerGlobalScope(scope) => {
24 scope.post_message_with_transfer(message, transfer)
25 }
26 Port::MessagePort(port) => port.post_message_with_transferable(message, transfer),
27 }
28 }
29
30 pub(crate) fn start(&self) {
31 if let Port::MessagePort(port) = self {
32 port.start()
33 }
34 }
35
36 pub(crate) fn event_target(&self) -> &web_sys::EventTarget {
37 match self {
38 Port::Worker(worker) => worker.as_ref(),
39 Port::DedicatedWorkerGlobalScope(scope) => scope.as_ref(),
40 Port::MessagePort(port) => port.as_ref(),
41 }
42 }
43}
44
45impl From<web_sys::Worker> for Port {
46 fn from(worker: web_sys::Worker) -> Self {
47 Port::Worker(worker.into())
48 }
49}
50
51impl From<web_sys::DedicatedWorkerGlobalScope> for Port {
52 fn from(scope: web_sys::DedicatedWorkerGlobalScope) -> Self {
53 Port::DedicatedWorkerGlobalScope(scope.into())
54 }
55}
56
57impl From<web_sys::MessagePort> for Port {
58 fn from(port: web_sys::MessagePort) -> Self {
59 Port::MessagePort(port.into())
60 }
61}
62
63impl Drop for Port {
64 fn drop(&mut self) {
65 if let Port::Worker(worker) = self {
66 if Rc::strong_count(worker) == 1 {
67 worker.terminate()
68 }
69 }
70 }
71}