use crate::{
core::{UntypedVal, ValType, F32, F64},
ExternRef,
Func,
FuncRef,
};
pub trait WithType {
type Output;
fn with_type(self, ty: ValType) -> Self::Output;
}
impl WithType for UntypedVal {
type Output = Val;
fn with_type(self, ty: ValType) -> Self::Output {
match ty {
ValType::I32 => Val::I32(self.into()),
ValType::I64 => Val::I64(self.into()),
ValType::F32 => Val::F32(self.into()),
ValType::F64 => Val::F64(self.into()),
ValType::FuncRef => Val::FuncRef(self.into()),
ValType::ExternRef => Val::ExternRef(self.into()),
}
}
}
impl From<Val> for UntypedVal {
fn from(value: Val) -> Self {
match value {
Val::I32(value) => value.into(),
Val::I64(value) => value.into(),
Val::F32(value) => value.into(),
Val::F64(value) => value.into(),
Val::FuncRef(value) => value.into(),
Val::ExternRef(value) => value.into(),
}
}
}
#[derive(Clone, Debug)]
pub enum Val {
I32(i32),
I64(i64),
F32(F32),
F64(F64),
FuncRef(FuncRef),
ExternRef(ExternRef),
}
impl Val {
#[inline]
pub fn default(value_type: ValType) -> Self {
match value_type {
ValType::I32 => Self::I32(0),
ValType::I64 => Self::I64(0),
ValType::F32 => Self::F32(0f32.into()),
ValType::F64 => Self::F64(0f64.into()),
ValType::FuncRef => Self::from(FuncRef::null()),
ValType::ExternRef => Self::from(ExternRef::null()),
}
}
#[inline]
pub fn ty(&self) -> ValType {
match *self {
Self::I32(_) => ValType::I32,
Self::I64(_) => ValType::I64,
Self::F32(_) => ValType::F32,
Self::F64(_) => ValType::F64,
Self::FuncRef(_) => ValType::FuncRef,
Self::ExternRef(_) => ValType::ExternRef,
}
}
pub fn i32(&self) -> Option<i32> {
match self {
Self::I32(value) => Some(*value),
_ => None,
}
}
pub fn i64(&self) -> Option<i64> {
match self {
Self::I64(value) => Some(*value),
_ => None,
}
}
pub fn f32(&self) -> Option<F32> {
match self {
Self::F32(value) => Some(*value),
_ => None,
}
}
pub fn f64(&self) -> Option<F64> {
match self {
Self::F64(value) => Some(*value),
_ => None,
}
}
pub fn funcref(&self) -> Option<&FuncRef> {
match self {
Self::FuncRef(value) => Some(value),
_ => None,
}
}
pub fn externref(&self) -> Option<&ExternRef> {
match self {
Self::ExternRef(value) => Some(value),
_ => None,
}
}
}
impl From<i32> for Val {
#[inline]
fn from(val: i32) -> Self {
Self::I32(val)
}
}
impl From<i64> for Val {
#[inline]
fn from(val: i64) -> Self {
Self::I64(val)
}
}
impl From<F32> for Val {
#[inline]
fn from(val: F32) -> Self {
Self::F32(val)
}
}
impl From<F64> for Val {
#[inline]
fn from(val: F64) -> Self {
Self::F64(val)
}
}
impl From<FuncRef> for Val {
#[inline]
fn from(funcref: FuncRef) -> Self {
Self::FuncRef(funcref)
}
}
impl From<Func> for Val {
#[inline]
fn from(func: Func) -> Self {
Self::FuncRef(FuncRef::new(func))
}
}
impl From<ExternRef> for Val {
#[inline]
fn from(externref: ExternRef) -> Self {
Self::ExternRef(externref)
}
}