wasm_rs_shared_channel/
lib.rs1use js_sys::Uint8Array;
9use thiserror::Error;
10use wasm_bindgen::prelude::*;
11
12pub mod spsc;
13
14#[derive(Debug, Clone, Error)]
16#[error("expects {0} bytes more")]
17pub struct Expects(pub u32);
18
19pub trait Shareable: Sized {
21 type Error: std::error::Error;
23 fn to_bytes(&self) -> Result<Uint8Array, Self::Error>;
25 fn from(bytes: &Uint8Array) -> Result<Result<Self, Expects>, Self::Error>;
27}
28
29#[cfg(feature = "serde")]
30impl<T> Shareable for T
31where
32 for<'a> T: serde::Serialize + serde::Deserialize<'a>,
33{
34 #[cfg(not(any(feature = "serde-bincode")))]
35 std::compile_error!("one of these features has to be enabled: serde-bincode");
36
37 #[cfg(feature = "serde-bincode")]
38 type Error = bincode::Error;
39
40 fn to_bytes(&self) -> Result<Uint8Array, Self::Error> {
41 #[cfg(feature = "serde-bincode")]
42 let mut result: Vec<u8> = (bincode::serialized_size(self)? as u32)
43 .to_ne_bytes()
44 .into();
45 #[cfg(feature = "serde-bincode")]
46 let mut encoded: Vec<u8> = bincode::serialize(self)?;
47 result.append(&mut encoded);
48 Ok(Uint8Array::from(&result[..]))
49 }
50 fn from(bytes: &Uint8Array) -> Result<Result<Self, Expects>, Self::Error> {
51 if bytes.byte_length() == 0 {
52 return Ok(Err(Expects(4))); }
54 if bytes.byte_length() >= 4 {
55 let mut data = vec![0; bytes.byte_length() as usize];
56 bytes.copy_to(&mut data);
57 let size = u32::from_ne_bytes([data[0], data[1], data[2], data[3]]);
58 if bytes.byte_length() == 4 {
59 return Ok(Err(Expects(4 + size))); }
61 #[cfg(feature = "serde-bincode")]
62 return Ok(Ok(bincode::deserialize::<Self>(&data[4..])?));
63 }
64
65 #[cfg(feature = "serde-bincode")]
66 Err(Box::new(bincode::ErrorKind::Custom(
67 "unexpected data".to_string(),
68 )))
69 }
70}