use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PortType {
U64,
F64,
U32,
I32,
I64,
F32,
U8,
I8,
U16,
I16,
F16,
U128,
I128,
Reg128,
RegI8x16,
RegI16x8,
RegI32x4,
RegI64x2,
RegF16x8,
RegF32x4,
RegF64x2,
Bool,
Str,
Bytes,
Json,
Ext,
Handle,
VecF32,
VecI32,
VecF64,
VecI64,
VecF16,
VecI16,
VecI8,
Dyn,
}
impl fmt::Display for PortType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PortType::U64 => write!(f, "u64"),
PortType::F64 => write!(f, "f64"),
PortType::U32 => write!(f, "u32"),
PortType::I32 => write!(f, "i32"),
PortType::I64 => write!(f, "i64"),
PortType::F32 => write!(f, "f32"),
PortType::U8 => write!(f, "u8"),
PortType::I8 => write!(f, "i8"),
PortType::U16 => write!(f, "u16"),
PortType::I16 => write!(f, "i16"),
PortType::F16 => write!(f, "f16"),
PortType::U128 => write!(f, "u128"),
PortType::I128 => write!(f, "i128"),
PortType::Reg128 => write!(f, "reg128"),
PortType::RegI8x16 => write!(f, "reg_i8x16"),
PortType::RegI16x8 => write!(f, "reg_i16x8"),
PortType::RegI32x4 => write!(f, "reg_i32x4"),
PortType::RegI64x2 => write!(f, "reg_i64x2"),
PortType::RegF16x8 => write!(f, "reg_f16x8"),
PortType::RegF32x4 => write!(f, "reg_f32x4"),
PortType::RegF64x2 => write!(f, "reg_f64x2"),
PortType::Bool => write!(f, "bool"),
PortType::Str => write!(f, "String"),
PortType::Bytes => write!(f, "bytes"),
PortType::Json => write!(f, "json"),
PortType::Ext => write!(f, "ext"),
PortType::Handle => write!(f, "handle"),
PortType::VecF32 => write!(f, "vec_f32"),
PortType::VecI32 => write!(f, "vec_i32"),
PortType::VecF64 => write!(f, "vec_f64"),
PortType::VecI64 => write!(f, "vec_i64"),
PortType::VecF16 => write!(f, "vec_f16"),
PortType::VecI16 => write!(f, "vec_i16"),
PortType::VecI8 => write!(f, "vec_i8"),
PortType::Dyn => write!(f, "dyn"),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum NumericDomain {
Unsigned {
bits: u32,
},
Signed {
bits: u32,
},
Float {
mantissa: u32,
exponent: u32,
},
}
impl NumericDomain {
pub fn fits_in(self, other: Self) -> bool {
use NumericDomain::{Float, Signed, Unsigned};
match (self, other) {
(Unsigned { bits: a }, Unsigned { bits: b }) => a <= b,
(Unsigned { bits: a }, Signed { bits: b }) => a < b,
(Signed { bits: a }, Signed { bits: b }) => a <= b,
(Signed { .. }, Unsigned { .. }) => false,
(Unsigned { bits }, Float { mantissa, .. }) => bits <= mantissa,
(Signed { bits }, Float { mantissa, .. }) => bits - 1 <= mantissa,
(Float { .. }, Unsigned { .. } | Signed { .. }) => false,
(
Float {
mantissa: m1,
exponent: e1,
},
Float {
mantissa: m2,
exponent: e2,
},
) => m1 <= m2 && e1 <= e2,
}
}
}
impl PortType {
pub const ALL: &'static [PortType] = &[
PortType::U64,
PortType::F64,
PortType::U32,
PortType::I32,
PortType::I64,
PortType::F32,
PortType::U8,
PortType::I8,
PortType::U16,
PortType::I16,
PortType::F16,
PortType::U128,
PortType::I128,
PortType::Reg128,
PortType::RegI8x16,
PortType::RegI16x8,
PortType::RegI32x4,
PortType::RegI64x2,
PortType::RegF16x8,
PortType::RegF32x4,
PortType::RegF64x2,
PortType::Bool,
PortType::Str,
PortType::Bytes,
PortType::Json,
PortType::Ext,
PortType::Handle,
PortType::VecF32,
PortType::VecI32,
PortType::VecF64,
PortType::VecI64,
PortType::VecF16,
PortType::VecI16,
PortType::VecI8,
PortType::Dyn,
];
#[doc(hidden)]
pub fn every_variant_is_listed(self) -> bool {
match self {
PortType::U64
| PortType::F64
| PortType::U32
| PortType::I32
| PortType::I64
| PortType::F32
| PortType::U8
| PortType::I8
| PortType::U16
| PortType::I16
| PortType::F16
| PortType::U128
| PortType::I128
| PortType::Reg128
| PortType::RegI8x16
| PortType::RegI16x8
| PortType::RegI32x4
| PortType::RegI64x2
| PortType::RegF16x8
| PortType::RegF32x4
| PortType::RegF64x2
| PortType::Bool
| PortType::Str
| PortType::Bytes
| PortType::Json
| PortType::Ext
| PortType::Handle
| PortType::VecF32
| PortType::VecI32
| PortType::VecF64
| PortType::VecI64
| PortType::VecF16
| PortType::VecI16
| PortType::VecI8
| PortType::Dyn => Self::ALL.contains(&self),
}
}
pub fn numeric_domain(self) -> Option<NumericDomain> {
use NumericDomain::{Float, Signed, Unsigned};
Some(match self {
Self::Bool => Unsigned { bits: 1 },
Self::U8 => Unsigned { bits: 8 },
Self::U16 => Unsigned { bits: 16 },
Self::U32 => Unsigned { bits: 32 },
Self::U64 => Unsigned { bits: 64 },
Self::U128 => Unsigned { bits: 128 },
Self::I8 => Signed { bits: 8 },
Self::I16 => Signed { bits: 16 },
Self::I32 => Signed { bits: 32 },
Self::I64 => Signed { bits: 64 },
Self::I128 => Signed { bits: 128 },
Self::F16 => Float {
mantissa: 11,
exponent: 5,
},
Self::F32 => Float {
mantissa: 24,
exponent: 8,
},
Self::F64 => Float {
mantissa: 53,
exponent: 11,
},
Self::Str
| Self::Bytes
| Self::Json
| Self::Ext
| Self::Handle
| Self::Reg128
| Self::RegI8x16
| Self::RegI16x8
| Self::RegI32x4
| Self::RegI64x2
| Self::RegF16x8
| Self::RegF32x4
| Self::RegF64x2
| Self::VecF32
| Self::VecI32
| Self::VecF64
| Self::VecI64
| Self::VecF16
| Self::VecI16
| Self::VecI8
| Self::Dyn => return None,
})
}
pub fn to_keyword(&self) -> &'static str {
match self {
Self::U64 => "u64",
Self::F64 => "f64",
Self::U32 => "u32",
Self::I32 => "i32",
Self::I64 => "i64",
Self::F32 => "f32",
Self::U8 => "u8",
Self::I8 => "i8",
Self::U16 => "u16",
Self::I16 => "i16",
Self::F16 => "f16",
Self::U128 => "u128",
Self::I128 => "i128",
Self::Reg128 => "reg128",
Self::RegI8x16 => "reg_i8x16",
Self::RegI16x8 => "reg_i16x8",
Self::RegI32x4 => "reg_i32x4",
Self::RegI64x2 => "reg_i64x2",
Self::RegF16x8 => "reg_f16x8",
Self::RegF32x4 => "reg_f32x4",
Self::RegF64x2 => "reg_f64x2",
Self::Bool => "bool",
Self::Str => "str",
Self::Bytes => "bytes",
Self::Json => "json",
Self::Ext => "ext",
Self::Handle => "handle",
Self::VecF32 => "vec_f32",
Self::VecI32 => "vec_i32",
Self::VecF64 => "vec_f64",
Self::VecI64 => "vec_i64",
Self::VecF16 => "vec_f16",
Self::VecI16 => "vec_i16",
Self::VecI8 => "vec_i8",
Self::Dyn => "dyn",
}
}
pub fn from_keyword(name: &str) -> Option<Self> {
match name {
"u64" => Some(Self::U64),
"f64" => Some(Self::F64),
"u32" => Some(Self::U32),
"i32" => Some(Self::I32),
"i64" => Some(Self::I64),
"f32" => Some(Self::F32),
"u8" => Some(Self::U8),
"i8" => Some(Self::I8),
"u16" => Some(Self::U16),
"i16" => Some(Self::I16),
"f16" => Some(Self::F16),
"u128" => Some(Self::U128),
"i128" => Some(Self::I128),
"reg128" => Some(Self::Reg128),
"reg_i8x16" => Some(Self::RegI8x16),
"reg_i16x8" => Some(Self::RegI16x8),
"reg_i32x4" => Some(Self::RegI32x4),
"reg_i64x2" => Some(Self::RegI64x2),
"reg_f16x8" => Some(Self::RegF16x8),
"reg_f32x4" => Some(Self::RegF32x4),
"reg_f64x2" => Some(Self::RegF64x2),
"bool" => Some(Self::Bool),
"str" | "Str" | "String" => Some(Self::Str),
"bytes" => Some(Self::Bytes),
"json" | "Json" => Some(Self::Json),
"ext" | "Ext" => Some(Self::Ext),
"handle" => Some(Self::Handle),
"vec_f32" => Some(Self::VecF32),
"vec_i32" => Some(Self::VecI32),
"vec_f64" => Some(Self::VecF64),
"vec_i64" => Some(Self::VecI64),
"vec_f16" => Some(Self::VecF16),
"vec_i16" => Some(Self::VecI16),
"vec_i8" => Some(Self::VecI8),
"dyn" => Some(Self::Dyn),
_ => None,
}
}
pub fn from_workload_name(name: &str) -> Option<Self> {
match Self::from_keyword(name)? {
Self::Handle | Self::Ext => None,
pt => Some(pt),
}
}
}