1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;
use wasm_bindgen::JsCast;
use js_sys::{ArrayBuffer, Function, Promise, Uint8Array};
use web_sys::{Response, TextDecoder, TextEncoder};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::cell::RefCell;
pub use super::{console_ln, debug_ln};
pub struct Counter(RefCell<usize>);
impl Counter {
pub fn new() -> Self {
Self(RefCell::new(0))
}
pub fn inc(&self) -> usize {
let mut num = self.0.borrow_mut();
*num += 1;
*num
}
pub fn num(&self) -> usize {
*self.0.borrow()
}
}
pub fn perf_to_system(amt: f64) -> SystemTime {
let secs = (amt as u64) / 1_000;
let nanos = ((amt as u32) % 1_000) * 1_000_000;
UNIX_EPOCH + Duration::new(secs, nanos)
}
pub fn u8arr_from_vec(vec: &[u8]) -> Uint8Array {
let arr = js_sys::Array::new();
for &el in vec {
arr.push(&JsValue::from(el));
}
Uint8Array::new(&arr)
}
pub fn ab_dup(ab: &ArrayBuffer) -> ArrayBuffer {
Uint8Array::new(ab).buffer()
}
pub fn ab_from_text(text: &str) -> ArrayBuffer {
u8arr_from_vec(
&TextEncoder::new().unwrap().encode_with_input(text))
.buffer()
}
pub fn text_from_ab(ab: &ArrayBuffer) -> Option<String> {
TextDecoder::new().ok()?
.decode_with_buffer_source(ab).ok()
}
pub async fn fetch_and_response(url: &str) -> Result<Response, JsValue> {
let obj = js_sys::global().unchecked_into::<web_sys::Window>();
let ret = JsFuture::from(obj.fetch_with_str(url)).await?
.unchecked_into::<Response>();
Ok(ret)
}
pub async fn fetch_as_text(url: &str) -> Result<String, JsValue> {
let resp = fetch_and_response(url).await?;
let ret = JsFuture::from(resp.text()?).await?
.as_string().unwrap_throw();
Ok(ret)
}
pub async fn fetch_as_arraybuffer(url: &str) -> Result<ArrayBuffer, JsValue> {
let resp = fetch_and_response(url).await?;
let ret = JsFuture::from(resp.array_buffer()?).await?
.unchecked_into::<ArrayBuffer>();
Ok(ret)
}
pub fn run_js(js: &str) -> Result<JsValue, JsValue> {
Function::new_no_args(js).call0(&JsValue::NULL)
}
pub async fn run_js_async(js: &str) -> Result<JsValue, JsValue> {
let mut body = String::from("return (async () => { ");
body.push_str(js);
body.push_str("})();");
let promise = Promise::new(&mut |res, rej| {
match Function::new_no_args(&body).call0(&JsValue::NULL) {
Ok(jsv) => res.call1(&JsValue::NULL, &jsv).unwrap(),
Err(jsv) => rej.call1(&JsValue::NULL, &jsv).unwrap(),
};
});
JsFuture::from(promise).await
}
pub async fn sleep(ms: u32) {
run_js_async(format!("
await (ms => new Promise((res, rej) => setTimeout(res, ms)))({});
", ms).as_str()).await.unwrap();
}