#![warn(missing_docs)]
use std::sync::{LazyLock, OnceLock};
use crate::host::{Request, Response};
pub mod host;
struct Handler {
guest: Box<dyn Guest>,
}
unsafe impl Send for Handler {}
unsafe impl Sync for Handler {}
pub trait Guest {
fn handle_request(&self, _request: &Request, _response: &Response) -> (bool, i32) {
(true, 0)
}
fn handle_response(&self, _req_ctx: i32, _request: &Request, _response: &Response, _is_error: bool) {}
}
static GUEST: OnceLock<Handler> = OnceLock::new();
static REQ: LazyLock<Request> = LazyLock::new(Request::default);
static RES: LazyLock<Response> = LazyLock::new(Response::default);
pub fn register<T: Guest + 'static>(guest: T) {
GUEST.get_or_init(|| Handler { guest: Box::new(guest) });
}
#[unsafe(export_name = "handle_request")]
fn http_request() -> i64 {
let (next, ctx_next) = match GUEST.get() {
Some(handler) => handler.guest.handle_request(&REQ, &RES),
None => (true, 0),
};
if next { (ctx_next as i64) << 32 | 1 } else { 0 }
}
#[unsafe(export_name = "handle_response")]
fn http_response(req_ctx: i32, is_error: i32) {
if let Some(handler) = GUEST.get() {
handler.guest.handle_response(req_ctx, &REQ, &RES, is_error == 1)
};
}