#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum WasmType {
#[default]
I32,
F32,
I64,
F64,
}
impl WasmType {
pub fn is_float(&self) -> bool {
matches!(self, WasmType::F32 | WasmType::F64)
}
pub fn is_integer(&self) -> bool {
matches!(self, WasmType::I32 | WasmType::I64)
}
pub fn is_64bit(&self) -> bool {
matches!(self, WasmType::I64 | WasmType::F64)
}
pub fn is_32bit(&self) -> bool {
matches!(self, WasmType::I32 | WasmType::F32)
}
pub fn byte_size(&self) -> usize {
match self {
WasmType::I32 | WasmType::F32 => 4,
WasmType::I64 | WasmType::F64 => 8,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wasm_type_is_float() {
assert!(WasmType::F32.is_float());
assert!(WasmType::F64.is_float());
assert!(!WasmType::I32.is_float());
assert!(!WasmType::I64.is_float());
}
#[test]
fn test_wasm_type_is_integer() {
assert!(WasmType::I32.is_integer());
assert!(WasmType::I64.is_integer());
assert!(!WasmType::F32.is_integer());
assert!(!WasmType::F64.is_integer());
}
#[test]
fn test_wasm_type_is_64bit() {
assert!(WasmType::I64.is_64bit());
assert!(WasmType::F64.is_64bit());
assert!(!WasmType::I32.is_64bit());
assert!(!WasmType::F32.is_64bit());
}
#[test]
fn test_wasm_type_is_32bit() {
assert!(WasmType::I32.is_32bit());
assert!(WasmType::F32.is_32bit());
assert!(!WasmType::I64.is_32bit());
assert!(!WasmType::F64.is_32bit());
}
#[test]
fn test_wasm_type_byte_size() {
assert_eq!(WasmType::I32.byte_size(), 4);
assert_eq!(WasmType::F32.byte_size(), 4);
assert_eq!(WasmType::I64.byte_size(), 8);
assert_eq!(WasmType::F64.byte_size(), 8);
}
#[test]
fn test_wasm_type_default() {
assert_eq!(WasmType::default(), WasmType::I32);
}
#[test]
fn test_wasm_type_debug() {
let debug = format!("{:?}", WasmType::I32);
assert!(debug.contains("I32"));
}
#[test]
fn test_wasm_type_clone() {
let ty = WasmType::F64;
let cloned = ty;
assert_eq!(ty, cloned);
}
#[test]
fn test_wasm_type_eq() {
assert_eq!(WasmType::I32, WasmType::I32);
assert_ne!(WasmType::I32, WasmType::F32);
}
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
fn arb_wasm_type() -> impl Strategy<Value = WasmType> {
prop_oneof![
Just(WasmType::I32),
Just(WasmType::F32),
Just(WasmType::I64),
Just(WasmType::F64),
]
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(100))]
#[test]
fn prop_float_xor_integer(ty in arb_wasm_type()) {
prop_assert!(ty.is_float() != ty.is_integer());
}
#[test]
fn prop_32bit_xor_64bit(ty in arb_wasm_type()) {
prop_assert!(ty.is_32bit() != ty.is_64bit());
}
#[test]
fn prop_byte_size_consistent(ty in arb_wasm_type()) {
let size = ty.byte_size();
if ty.is_32bit() {
prop_assert_eq!(size, 4);
} else {
prop_assert_eq!(size, 8);
}
}
}
}
}