#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
use core::fmt;
pub use use_wasm_value::{
WasmValueType as FunctionValueType, WasmValueTypeError as WasmFunctionError,
};
macro_rules! index_newtype {
($name:ident) => {
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct $name(u32);
impl $name {
#[must_use]
pub const fn new(index: u32) -> Self {
Self(index)
}
#[must_use]
pub const fn get(self) -> u32 {
self.0
}
}
impl fmt::Display for $name {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.get())
}
}
};
}
index_newtype!(FunctionIndex);
index_newtype!(TypeIndex);
index_newtype!(LocalIndex);
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
pub struct ParameterList(Vec<FunctionValueType>);
impl ParameterList {
#[must_use]
pub fn new(values: Vec<FunctionValueType>) -> Self {
Self(values)
}
#[must_use]
pub const fn empty() -> Self {
Self(Vec::new())
}
#[must_use]
pub fn as_slice(&self) -> &[FunctionValueType] {
&self.0
}
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
pub struct ResultList(Vec<FunctionValueType>);
impl ResultList {
#[must_use]
pub fn new(values: Vec<FunctionValueType>) -> Self {
Self(values)
}
#[must_use]
pub const fn empty() -> Self {
Self(Vec::new())
}
#[must_use]
pub fn as_slice(&self) -> &[FunctionValueType] {
&self.0
}
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
pub struct FunctionSignature {
params: ParameterList,
results: ResultList,
}
impl FunctionSignature {
#[must_use]
pub const fn new(params: ParameterList, results: ResultList) -> Self {
Self { params, results }
}
#[must_use]
pub const fn params(&self) -> &ParameterList {
&self.params
}
#[must_use]
pub const fn results(&self) -> &ResultList {
&self.results
}
}
#[cfg(test)]
mod tests {
use super::{
FunctionIndex, FunctionSignature, FunctionValueType, ParameterList, ResultList,
WasmFunctionError,
};
#[test]
fn wraps_indexes_and_value_types() {
let index = FunctionIndex::new(3);
let value_type = "extern-ref"
.parse::<FunctionValueType>()
.expect("known type");
assert_eq!(index.get(), 3);
assert_eq!(index.to_string(), "3");
assert_eq!(value_type, FunctionValueType::ExternRef);
assert_eq!(
"".parse::<FunctionValueType>(),
Err(WasmFunctionError::Empty)
);
}
#[test]
fn stores_signature_metadata() {
let signature = FunctionSignature::new(
ParameterList::new(vec![FunctionValueType::I32, FunctionValueType::I64]),
ResultList::new(vec![FunctionValueType::I32]),
);
assert_eq!(signature.params().len(), 2);
assert_eq!(signature.results().as_slice(), &[FunctionValueType::I32]);
}
}