use crate::wire::{APP_KEY, ATTACHMENTS_KEY, Attachments, MESSAGE_KEY};
use serde::Serialize;
use wasm_bindgen::{JsCast, JsValue};
pub fn envelope_with<Message: Serialize>(key: &str, message: &Message) -> Option<js_sys::Object> {
let value = serde_wasm_bindgen::to_value(message).ok()?;
let envelope = js_sys::Object::new();
js_sys::Reflect::set(&envelope, &JsValue::from_str(key), &value).ok()?;
Some(envelope)
}
pub fn attach(
envelope: &js_sys::Object,
transfer: &js_sys::Array,
attachments: &[(String, Vec<u8>)],
) -> bool {
let bag = js_sys::Object::new();
for (name, bytes) in attachments {
let array = js_sys::Uint8Array::new_with_length(bytes.len() as u32);
array.copy_from(bytes);
if js_sys::Reflect::set(&bag, &JsValue::from_str(name), &array).is_err() {
return false;
}
transfer.push(&array.buffer());
}
js_sys::Reflect::set(envelope, &JsValue::from_str(ATTACHMENTS_KEY), &bag).is_ok()
}
pub fn control_value_from(data: &JsValue) -> Option<JsValue> {
field(data, MESSAGE_KEY)
}
pub fn app_value_from(data: &JsValue) -> Option<JsValue> {
field(data, APP_KEY)
}
fn field(data: &JsValue, key: &str) -> Option<JsValue> {
let value = js_sys::Reflect::get(data, &JsValue::from_str(key)).ok()?;
if value.is_undefined() || value.is_null() {
return None;
}
Some(value)
}
pub fn attachments_from(data: &JsValue) -> Attachments {
let mut attachments = Vec::new();
let Ok(value) = js_sys::Reflect::get(data, &JsValue::from_str(ATTACHMENTS_KEY)) else {
return attachments;
};
if !value.is_object() {
return attachments;
}
let object: js_sys::Object = value.clone().unchecked_into();
for key in js_sys::Object::keys(&object).iter() {
if let Some(name) = key.as_string()
&& let Ok(entry) = js_sys::Reflect::get(&value, &key)
&& let Ok(array) = entry.dyn_into::<js_sys::Uint8Array>()
{
attachments.push((name, array.to_vec()));
}
}
attachments
}