use js_sys::{Map, Object, Reflect}; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::JsFuture; use crate::{Fetcher, Result}; #[derive(Debug)] pub struct Container { pub(super) inner: worker_sys::Container, } impl Container { pub fn running(&self) -> bool { self.inner.running() } pub fn start(&self, options: Option) -> Result<()> { let options = match options { Some(o) => o.into(), None => JsValue::undefined(), }; self.inner.start(&options).map_err(|e| e.into()) } pub async fn wait_for_exit(&self) -> Result<()> { let promise = self.inner.monitor(); JsFuture::from(promise).await?; Ok(()) } pub async fn destroy(&self, error: Option<&str>) -> Result<()> { let promise = self.inner.destroy(error); JsFuture::from(promise).await?; Ok(()) } pub fn signal(&self, signo: i32) -> Result<()> { self.inner.signal(signo).map_err(|e| e.into()) } pub fn get_tcp_port(&self, port: u16) -> Result { self.inner .get_tcp_port(port) .map(|f| f.into()) .map_err(|e| e.into()) } } unsafe impl Sync for Container {} unsafe impl Send for Container {} impl From for Container { fn from(inner: worker_sys::Container) -> Self { Self { inner } } } impl AsRef for Container { fn as_ref(&self) -> &JsValue { &self.inner } } impl From for JsValue { fn from(container: Container) -> Self { JsValue::from(container.inner) } } impl JsCast for Container { fn instanceof(val: &JsValue) -> bool { val.is_instance_of::() } fn unchecked_from_js(val: JsValue) -> Self { Self { inner: val.into() } } fn unchecked_from_js_ref(val: &JsValue) -> &Self { unsafe { &*(val as *const JsValue as *const Self) } } } #[wasm_bindgen(getter_with_clone)] #[derive(Debug, Clone)] pub struct ContainerStartupOptions { pub entrypoint: Vec, #[wasm_bindgen(js_name = "enableInternet")] pub enable_internet: Option, pub env: Map, } impl ContainerStartupOptions { pub fn new() -> ContainerStartupOptions { ContainerStartupOptions { entrypoint: Vec::new(), enable_internet: None, env: Map::new(), } } pub fn set_entrypoint(&mut self, entrypoint: &[&str]) { self.entrypoint = entrypoint.iter().map(|s| s.to_string()).collect(); } pub fn enable_internet(&mut self, enable_internet: bool) { self.enable_internet = Some(enable_internet); } pub fn add_env(&mut self, key: &str, value: &str) { self.env .set(&JsValue::from_str(key), &JsValue::from_str(value)); } } impl From for Object { fn from(options: ContainerStartupOptions) -> Self { let obj = options.clone().into(); if !options.entrypoint.is_empty() { Reflect::delete_property(&obj, &JsValue::from_str("entrypoint")).unwrap(); } if options.enable_internet.is_some() { Reflect::delete_property(&obj, &JsValue::from_str("enableInternet")).unwrap(); } if options.env.size() != 0 { Reflect::delete_property(&obj, &JsValue::from_str("env")).unwrap(); } obj } }