use js_sys::{ArrayBuffer, Uint8Array};
use wasm_bindgen::JsCast;
use web_sys::{Blob, MessageEvent};
use crate::WsErr;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum WsMessage {
Text(String),
Binary(Vec<u8>),
}
impl TryFrom<MessageEvent> for WsMessage {
type Error = WsErr;
fn try_from(evt: MessageEvent) -> Result<Self, Self::Error> {
match evt.data() {
d if d.is_instance_of::<ArrayBuffer>() => {
let buffy = Uint8Array::new(d.unchecked_ref());
let mut v = vec![0; buffy.length() as usize];
buffy.copy_to(&mut v);
Ok(WsMessage::Binary(v))
}
d if d.is_string() => match d.as_string() {
Some(text) => Ok(WsMessage::Text(text)),
None => Err(WsErr::InvalidEncoding),
},
d if d.is_instance_of::<Blob>() => Err(WsErr::CantDecodeBlob),
_ => Err(WsErr::UnknownDataType),
}
}
}
impl From<WsMessage> for Vec<u8> {
fn from(msg: WsMessage) -> Self {
match msg {
WsMessage::Text(string) => string.into(),
WsMessage::Binary(vec) => vec,
}
}
}
impl From<Vec<u8>> for WsMessage {
fn from(vec: Vec<u8>) -> Self {
WsMessage::Binary(vec)
}
}
impl From<String> for WsMessage {
fn from(s: String) -> Self {
WsMessage::Text(s)
}
}
impl AsRef<[u8]> for WsMessage {
fn as_ref(&self) -> &[u8] {
match self {
WsMessage::Text(string) => string.as_ref(),
WsMessage::Binary(vec) => vec.as_ref(),
}
}
}