pub mod cron;
pub mod fs;
pub mod http;
pub mod ipc;
pub mod kv;
pub mod shim;
pub mod sys;
pub mod uplink;
pub mod util;
use crate::engine::wasm::host_state::HostState;
use extism::{PluginBuilder, UserData, ValType};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WasmHostFunction {
FsExists,
FsMkdir,
FsReaddir,
FsStat,
FsUnlink,
ReadFile,
WriteFile,
IpcPublish,
IpcSubscribe,
IpcUnsubscribe,
IpcPoll,
UplinkRegister,
UplinkSend,
KvGet,
KvSet,
GetConfig,
HttpRequest,
Log,
CronSchedule,
CronCancel,
}
impl WasmHostFunction {
pub const ALL: [Self; 20] = [
Self::FsExists,
Self::FsMkdir,
Self::FsReaddir,
Self::FsStat,
Self::FsUnlink,
Self::ReadFile,
Self::WriteFile,
Self::IpcPublish,
Self::IpcSubscribe,
Self::IpcUnsubscribe,
Self::IpcPoll,
Self::UplinkRegister,
Self::UplinkSend,
Self::KvGet,
Self::KvSet,
Self::GetConfig,
Self::HttpRequest,
Self::Log,
Self::CronSchedule,
Self::CronCancel,
];
#[must_use]
pub fn from_index(index: usize) -> Option<Self> {
Self::ALL.get(index).copied()
}
#[must_use]
pub fn name(self) -> &'static str {
match self {
Self::FsExists => "astrid_fs_exists",
Self::FsMkdir => "astrid_fs_mkdir",
Self::FsReaddir => "astrid_fs_readdir",
Self::FsStat => "astrid_fs_stat",
Self::FsUnlink => "astrid_fs_unlink",
Self::ReadFile => "astrid_read_file",
Self::WriteFile => "astrid_write_file",
Self::IpcPublish => "astrid_ipc_publish",
Self::IpcSubscribe => "astrid_ipc_subscribe",
Self::IpcUnsubscribe => "astrid_ipc_unsubscribe",
Self::IpcPoll => "astrid_ipc_poll",
Self::UplinkRegister => "astrid_uplink_register",
Self::UplinkSend => "astrid_uplink_send",
Self::KvGet => "astrid_kv_get",
Self::KvSet => "astrid_kv_set",
Self::GetConfig => "astrid_get_config",
Self::HttpRequest => "astrid_http_request",
Self::Log => "astrid_log",
Self::CronSchedule => "astrid_cron_schedule",
Self::CronCancel => "astrid_cron_cancel",
}
}
#[must_use]
pub fn arg_count(self) -> usize {
match self {
Self::FsExists
| Self::FsMkdir
| Self::FsReaddir
| Self::FsStat
| Self::FsUnlink
| Self::ReadFile
| Self::IpcSubscribe
| Self::IpcUnsubscribe
| Self::IpcPoll
| Self::KvGet
| Self::GetConfig
| Self::HttpRequest
| Self::CronCancel => 1,
Self::WriteFile | Self::IpcPublish | Self::KvSet | Self::Log => 2,
Self::UplinkRegister | Self::UplinkSend | Self::CronSchedule => 3,
}
}
#[must_use]
pub fn return_type(self) -> i32 {
use shim::{TYPE_I64, TYPE_VOID};
match self {
Self::FsMkdir
| Self::FsUnlink
| Self::WriteFile
| Self::IpcPublish
| Self::IpcUnsubscribe
| Self::KvSet
| Self::Log
| Self::CronSchedule
| Self::CronCancel => TYPE_VOID,
Self::FsExists
| Self::FsReaddir
| Self::FsStat
| Self::ReadFile
| Self::IpcSubscribe
| Self::IpcPoll
| Self::UplinkRegister
| Self::UplinkSend
| Self::KvGet
| Self::GetConfig
| Self::HttpRequest => TYPE_I64,
}
}
}
pub fn register_host_functions(
mut builder: PluginBuilder,
user_data: UserData<HostState>,
) -> PluginBuilder {
for func in WasmHostFunction::ALL {
let ud = user_data.clone();
let args = vec![extism::PTR; func.arg_count()];
let rets = if func.return_type() == shim::TYPE_I64 {
vec![extism::PTR]
} else {
vec![]
};
builder = match func {
WasmHostFunction::FsExists => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_fs_exists_impl)
},
WasmHostFunction::FsMkdir => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_fs_mkdir_impl)
},
WasmHostFunction::FsReaddir => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_fs_readdir_impl)
},
WasmHostFunction::FsStat => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_fs_stat_impl)
},
WasmHostFunction::FsUnlink => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_fs_unlink_impl)
},
WasmHostFunction::ReadFile => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_read_file_impl)
},
WasmHostFunction::WriteFile => {
builder.with_function(func.name(), args, rets, ud, fs::astrid_write_file_impl)
},
WasmHostFunction::IpcPublish => {
builder.with_function(func.name(), args, rets, ud, ipc::astrid_ipc_publish_impl)
},
WasmHostFunction::IpcSubscribe => {
builder.with_function(func.name(), args, rets, ud, ipc::astrid_ipc_subscribe_impl)
},
WasmHostFunction::IpcUnsubscribe => builder.with_function(
func.name(),
args,
rets,
ud,
ipc::astrid_ipc_unsubscribe_impl,
),
WasmHostFunction::IpcPoll => {
builder.with_function(func.name(), args, rets, ud, ipc::astrid_ipc_poll_impl)
},
WasmHostFunction::UplinkRegister => builder.with_function(
func.name(),
args,
rets,
ud,
uplink::astrid_uplink_register_impl,
),
WasmHostFunction::UplinkSend => {
builder.with_function(func.name(), args, rets, ud, uplink::astrid_uplink_send_impl)
},
WasmHostFunction::KvGet => {
builder.with_function(func.name(), args, rets, ud, kv::astrid_kv_get_impl)
},
WasmHostFunction::KvSet => {
builder.with_function(func.name(), args, rets, ud, kv::astrid_kv_set_impl)
},
WasmHostFunction::GetConfig => {
builder.with_function(func.name(), args, rets, ud, sys::astrid_get_config_impl)
},
WasmHostFunction::HttpRequest => {
builder.with_function(func.name(), args, rets, ud, http::astrid_http_request_impl)
},
WasmHostFunction::Log => {
builder.with_function(func.name(), args, rets, ud, sys::astrid_log_impl)
},
WasmHostFunction::CronSchedule => {
builder.with_function(func.name(), args, rets, ud, cron::astrid_cron_schedule_impl)
},
WasmHostFunction::CronCancel => {
builder.with_function(func.name(), args, rets, ud, cron::astrid_cron_cancel_impl)
},
};
}
builder
.with_function_in_namespace(
"shim",
"__get_function_arg_type",
[ValType::I32, ValType::I32],
[ValType::I32],
UserData::new(()),
shim::shim_get_function_arg_type,
)
.with_function_in_namespace(
"shim",
"__get_function_return_type",
[ValType::I32],
[ValType::I32],
UserData::new(()),
shim::shim_get_function_return_type,
)
.with_function_in_namespace(
"shim",
"__invokeHostFunc",
[
ValType::I32,
ValType::I64,
ValType::I64,
ValType::I64,
ValType::I64,
ValType::I64,
],
[ValType::I64],
user_data,
shim::shim_invoke_host_func,
)
}