[go: up one dir, main page]

worker/
container.rs

1use js_sys::{Map, Object, Reflect};
2use wasm_bindgen::prelude::*;
3use wasm_bindgen_futures::JsFuture;
4
5use crate::{Fetcher, Result};
6
7#[derive(Debug)]
8pub struct Container {
9    pub(super) inner: worker_sys::Container,
10}
11
12impl Container {
13    pub fn running(&self) -> bool {
14        self.inner.running()
15    }
16
17    pub fn start(&self, options: Option<ContainerStartupOptions>) -> Result<()> {
18        let options = match options {
19            Some(o) => o.into(),
20            None => JsValue::undefined(),
21        };
22        self.inner.start(&options).map_err(|e| e.into())
23    }
24
25    pub async fn wait_for_exit(&self) -> Result<()> {
26        let promise = self.inner.monitor();
27        JsFuture::from(promise).await?;
28        Ok(())
29    }
30
31    pub async fn destroy(&self, error: Option<&str>) -> Result<()> {
32        let promise = self.inner.destroy(error);
33        JsFuture::from(promise).await?;
34        Ok(())
35    }
36
37    pub fn signal(&self, signo: i32) -> Result<()> {
38        self.inner.signal(signo).map_err(|e| e.into())
39    }
40
41    pub fn get_tcp_port(&self, port: u16) -> Result<Fetcher> {
42        self.inner
43            .get_tcp_port(port)
44            .map(|f| f.into())
45            .map_err(|e| e.into())
46    }
47}
48
49unsafe impl Sync for Container {}
50unsafe impl Send for Container {}
51
52impl From<worker_sys::Container> for Container {
53    fn from(inner: worker_sys::Container) -> Self {
54        Self { inner }
55    }
56}
57
58impl AsRef<JsValue> for Container {
59    fn as_ref(&self) -> &JsValue {
60        &self.inner
61    }
62}
63
64impl From<Container> for JsValue {
65    fn from(container: Container) -> Self {
66        JsValue::from(container.inner)
67    }
68}
69
70impl JsCast for Container {
71    fn instanceof(val: &JsValue) -> bool {
72        val.is_instance_of::<worker_sys::Container>()
73    }
74
75    fn unchecked_from_js(val: JsValue) -> Self {
76        Self { inner: val.into() }
77    }
78
79    fn unchecked_from_js_ref(val: &JsValue) -> &Self {
80        unsafe { &*(val as *const JsValue as *const Self) }
81    }
82}
83
84#[wasm_bindgen(getter_with_clone)]
85#[derive(Debug, Clone)]
86pub struct ContainerStartupOptions {
87    pub entrypoint: Vec<String>,
88    #[wasm_bindgen(js_name = "enableInternet")]
89    pub enable_internet: Option<bool>,
90    pub env: Map,
91}
92
93impl ContainerStartupOptions {
94    pub fn new() -> ContainerStartupOptions {
95        ContainerStartupOptions {
96            entrypoint: Vec::new(),
97            enable_internet: None,
98            env: Map::new(),
99        }
100    }
101
102    pub fn set_entrypoint(&mut self, entrypoint: &[&str]) {
103        self.entrypoint = entrypoint.iter().map(|s| s.to_string()).collect();
104    }
105
106    pub fn enable_internet(&mut self, enable_internet: bool) {
107        self.enable_internet = Some(enable_internet);
108    }
109
110    pub fn add_env(&mut self, key: &str, value: &str) {
111        self.env
112            .set(&JsValue::from_str(key), &JsValue::from_str(value));
113    }
114}
115
116impl From<ContainerStartupOptions> for Object {
117    fn from(options: ContainerStartupOptions) -> Self {
118        let obj = options.clone().into();
119        if !options.entrypoint.is_empty() {
120            Reflect::delete_property(&obj, &JsValue::from_str("entrypoint")).unwrap();
121        }
122        if options.enable_internet.is_some() {
123            Reflect::delete_property(&obj, &JsValue::from_str("enableInternet")).unwrap();
124        }
125        if options.env.size() != 0 {
126            Reflect::delete_property(&obj, &JsValue::from_str("env")).unwrap();
127        }
128        obj
129    }
130}