#![doc(html_root_url = "https://docs.rs/typed-array/0.2.0")]
use core::convert::TryFrom;
use err_derive::*;
use js_sys::{
ArrayBuffer, Float32Array, Float64Array, Int16Array, Int32Array, Int8Array, Uint16Array,
Uint32Array, Uint8Array, Uint8ClampedArray,
};
use wasm_bindgen::{JsCast, JsValue};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default, Error)]
#[error(display = "could not convert TypedArray to typed array instance")]
pub struct TryFromTypedArrayError {
_priv: (),
}
macro_rules! impl_from {
($arr:ident) => {
impl From<$arr> for TypedArray {
fn from(i: $arr) -> Self {
TypedArray::$arr(i)
}
}
impl TryFrom<TypedArray> for $arr {
type Error = TryFromTypedArrayError;
fn try_from(i: TypedArray) -> Result<Self, Self::Error> {
if let TypedArray::$arr(inner) = i {
Ok(inner)
} else {
Err(TryFromTypedArrayError::default())
}
}
}
};
}
#[derive(Clone, Debug)]
pub enum TypedArray {
Int8Array(Int8Array),
Uint8Array(Uint8Array),
Uint8ClampedArray(Uint8ClampedArray),
Int16Array(Int16Array),
Uint16Array(Uint16Array),
Int32Array(Int32Array),
Uint32Array(Uint32Array),
Float32Array(Float32Array),
Float64Array(Float64Array),
}
impl_from!(Int8Array);
impl_from!(Uint8Array);
impl_from!(Uint8ClampedArray);
impl_from!(Int16Array);
impl_from!(Uint16Array);
impl_from!(Int32Array);
impl_from!(Uint32Array);
impl_from!(Float32Array);
impl_from!(Float64Array);
macro_rules! match_every {
($to_match:expr, $name:ident, $x:expr) => {
match $to_match {
TypedArray::Int8Array($name) => $x,
TypedArray::Uint8Array($name) => $x,
TypedArray::Uint8ClampedArray($name) => $x,
TypedArray::Int16Array($name) => $x,
TypedArray::Uint16Array($name) => $x,
TypedArray::Int32Array($name) => $x,
TypedArray::Uint32Array($name) => $x,
TypedArray::Float32Array($name) => $x,
TypedArray::Float64Array($name) => $x,
}
};
}
impl TypedArray {
pub fn buffer(&self) -> ArrayBuffer {
match_every!(self, i, i.buffer())
}
pub fn subarray(&self, begin: u32, end: u32) -> Self {
match_every!(self, i, i.subarray(begin, end).into())
}
pub fn slice(&self, begin: u32, end: u32) -> Self {
match_every!(self, i, i.slice(begin, end).into())
}
pub fn length(&self) -> u32 {
match_every!(self, i, i.length())
}
pub fn byte_length(&self) -> u32 {
match_every!(self, i, i.byte_length())
}
pub fn byte_offset(&self) -> u32 {
match_every!(self, i, i.byte_offset())
}
pub fn set(&self, src: &JsValue, offset: u32) {
match_every!(self, i, i.set(src, offset))
}
pub fn has_type(i: JsValue) -> bool {
i.has_type::<Int8Array>()
|| i.has_type::<Uint8Array>()
|| i.has_type::<Uint8ClampedArray>()
|| i.has_type::<Int16Array>()
|| i.has_type::<Uint16Array>()
|| i.has_type::<Int32Array>()
|| i.has_type::<Uint32Array>()
|| i.has_type::<Float32Array>()
|| i.has_type::<Float64Array>()
}
pub fn dyn_into(i: JsValue) -> Result<Self, JsValue> {
JsCast::dyn_into::<Int8Array>(i)
.map(TypedArray::from)
.or_else(|e| JsCast::dyn_into::<Uint8Array>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Uint8ClampedArray>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Int16Array>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Uint16Array>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Int32Array>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Uint32Array>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Float32Array>(e).map(TypedArray::from))
.or_else(|e| JsCast::dyn_into::<Float64Array>(e).map(TypedArray::from))
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default, Error)]
#[error(display = "could not convert JsValue to TypedArray")]
pub struct TryFromJsValueError {
_priv: (),
}
impl TryFrom<JsValue> for TypedArray {
type Error = TryFromJsValueError;
fn try_from(i: JsValue) -> Result<Self, Self::Error> {
TypedArray::dyn_into(i).map_err(|_| TryFromJsValueError::default())
}
}
impl AsRef<JsValue> for TypedArray {
fn as_ref(&self) -> &JsValue {
match_every!(self, i, i.as_ref())
}
}
impl AsRef<js_sys::Object> for TypedArray {
fn as_ref(&self) -> &js_sys::Object {
match_every!(self, i, i.as_ref())
}
}