use std::collections::HashMap;
use arora_types::module::low::{ExportFunction, TypeRef};
use arora_types::record::module::frozen::{Function, Parameter};
use arora_types::record::ty::{FrozenTy, PrimitiveKind};
use arora_types::ty;
use uuid::Uuid;
fn primitive_kind_of(id: Uuid) -> Option<PrimitiveKind> {
use PrimitiveKind::*;
let table = [
(*ty::UNIT_ID, Unit),
(*ty::BOOLEAN_ID, Boolean),
(*ty::U8_ID, U8),
(*ty::U16_ID, U16),
(*ty::U32_ID, U32),
(*ty::U64_ID, U64),
(*ty::I8_ID, I8),
(*ty::I16_ID, I16),
(*ty::I32_ID, I32),
(*ty::I64_ID, I64),
(*ty::F32_ID, F32),
(*ty::F64_ID, F64),
(*ty::STRING_ID, String),
(*ty::ARRAY_BOOLEAN_ID, ArrayBoolean),
(*ty::ARRAY_U8_ID, ArrayU8),
(*ty::ARRAY_U16_ID, ArrayU16),
(*ty::ARRAY_U32_ID, ArrayU32),
(*ty::ARRAY_U64_ID, ArrayU64),
(*ty::ARRAY_I8_ID, ArrayI8),
(*ty::ARRAY_I16_ID, ArrayI16),
(*ty::ARRAY_I32_ID, ArrayI32),
(*ty::ARRAY_I64_ID, ArrayI64),
(*ty::ARRAY_F32_ID, ArrayF32),
(*ty::ARRAY_F64_ID, ArrayF64),
(*ty::ARRAY_STRING_ID, ArrayString),
];
table.iter().find(|(k, _)| *k == id).map(|(_, v)| *v)
}
fn array_kind_of(element: PrimitiveKind) -> Option<PrimitiveKind> {
use PrimitiveKind::*;
Some(match element {
Boolean => ArrayBoolean,
U8 => ArrayU8,
U16 => ArrayU16,
U32 => ArrayU32,
U64 => ArrayU64,
I8 => ArrayI8,
I16 => ArrayI16,
I32 => ArrayI32,
I64 => ArrayI64,
F32 => ArrayF32,
F64 => ArrayF64,
String => ArrayString,
_ => return None,
})
}
fn freeze_type_ref(ty: &TypeRef) -> Option<FrozenTy> {
match ty {
TypeRef::Scalar { id } => primitive_kind_of(*id).map(FrozenTy::from),
TypeRef::Array { id } => array_kind_of(primitive_kind_of(*id)?).map(FrozenTy::from),
TypeRef::FixedArray { .. } | TypeRef::Map { .. } | TypeRef::Option { .. } => None,
}
}
pub(crate) fn guest_function_signature(function: &ExportFunction) -> Option<Function> {
let mut parameters = HashMap::new();
let mut parameter_ordering = Vec::with_capacity(function.parameters.len());
for param in &function.parameters {
parameters.insert(
param.id,
Parameter {
name: param.name.clone(),
ty: freeze_type_ref(¶m.ty)?,
mutable: param.mutable,
},
);
parameter_ordering.push(param.id);
}
Some(Function {
parameters,
parameter_ordering,
return_ty: freeze_type_ref(&function.ret)?,
})
}