1use crate::{UntypedVal, ValType, F32, F64, V128};
2
3pub trait Typed {
5 const TY: ValType;
7}
8macro_rules! impl_typed_for {
9 ( $( $ty:ty => $value_ty:expr );* $(;)? ) => {
10 $(
11 impl Typed for $ty {
12 const TY: ValType = $value_ty;
13 }
14 )*
15 };
16}
17impl_typed_for! {
18 bool => ValType::I32;
19 i8 => ValType::I32;
20 u8 => ValType::I32;
21 i16 => ValType::I32;
22 u16 => ValType::I32;
23 i32 => ValType::I32;
24 u32 => ValType::I32;
25 i64 => ValType::I64;
26 u64 => ValType::I64;
27 f32 => ValType::F32;
28 f64 => ValType::F64;
29 F32 => ValType::F32;
30 F64 => ValType::F64;
31 V128 => ValType::V128;
32}
33
34impl From<TypedVal> for UntypedVal {
35 fn from(typed_value: TypedVal) -> Self {
36 typed_value.value
37 }
38}
39
40#[derive(Debug, Copy, Clone, PartialEq, Eq)]
51pub struct TypedVal {
52 ty: ValType,
54 value: UntypedVal,
56}
57
58impl TypedVal {
59 pub fn new(ty: ValType, value: UntypedVal) -> Self {
61 Self { ty, value }
62 }
63
64 pub fn ty(&self) -> ValType {
66 self.ty
67 }
68
69 pub fn untyped(&self) -> UntypedVal {
71 self.value
72 }
73}
74
75impl<T> From<T> for TypedVal
76where
77 T: Typed + Into<UntypedVal>,
78{
79 fn from(value: T) -> Self {
80 Self::new(<T as Typed>::TY, value.into())
81 }
82}
83
84macro_rules! impl_from_typed_value_for {
85 ( $( $( #[$attr:meta] )* impl From<TypedVal> for $ty:ty );* $(;)? ) => {
86 $(
87 $( #[$attr] )*
88 impl From<TypedVal> for $ty {
89 fn from(typed_value: TypedVal) -> Self {
90 debug_assert!(matches!(typed_value.ty, <$ty as Typed>::TY));
97 Self::from(typed_value.value)
98 }
99 }
100 )*
101 };
102}
103impl_from_typed_value_for! {
104 impl From<TypedVal> for bool;
105 impl From<TypedVal> for i32;
106 impl From<TypedVal> for u32;
107 impl From<TypedVal> for i64;
108 impl From<TypedVal> for u64;
109 impl From<TypedVal> for f32;
110 impl From<TypedVal> for f64;
111 #[cfg(feature = "simd")]
112 impl From<TypedVal> for V128;
113}
114
115macro_rules! impl_from_typed_value_as_for {
116 ( $( $( #[$attr:meta] )* impl From<TypedVal> for $ty:ty as $as:ty );* $(;)? ) => {
117 $(
118 $( #[$attr] )*
119 impl From<TypedVal> for $ty {
120 fn from(typed_value: TypedVal) -> Self {
121 <$as as From<TypedVal>>::from(typed_value) as $ty
122 }
123 }
124 )*
125 };
126}
127impl_from_typed_value_as_for! {
128 impl From<TypedVal> for i8 as i32;
129 impl From<TypedVal> for i16 as i32;
130 impl From<TypedVal> for u8 as u32;
131 impl From<TypedVal> for u16 as u32;
132}