1pub mod wasm_types;
13
14mod macros;
15mod plugin_ctx;
16mod wasm_ctx;
17
18pub use crate::plugin_ctx::{
19 FormPart, HttpRequest, HttpRequestBuilder, HttpResponse, LOG_DEBUG, LOG_ERROR, LOG_INFO,
20 LOG_TRACE, LOG_WARN, PluginContext,
21};
22use aiway_protocol::context::http::{request, response};
23pub use async_trait::async_trait;
24pub use bincode;
25pub use bytes::Bytes;
26pub use http;
27pub use semver::Version;
28pub use serde_json;
29use serde_json::Value;
30pub use wasm_ctx::WasmHttpContext;
31#[derive(Debug)]
33pub enum PluginError {
34 ExecuteError(String),
36 NotFound(String),
38 LoadError(String),
40 SerializeError(String),
42 HttpError(String),
44 Reject(u16, String),
49}
50
51impl std::fmt::Display for PluginError {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 match self {
54 PluginError::ExecuteError(msg) => write!(f, "{}", msg),
55 PluginError::NotFound(msg) => write!(f, "{}", msg),
56 PluginError::LoadError(msg) => write!(f, "{}", msg),
57 PluginError::SerializeError(msg) => write!(f, "{}", msg),
58 PluginError::HttpError(msg) => write!(f, "{}", msg),
59 PluginError::Reject(status, message) => write!(f, "[{}] {}", status, message),
60 }
61 }
62}
63
64#[async_trait]
69pub trait Plugin: Send + Sync {
70 fn name(&self) -> &str;
72 fn info(&self) -> PluginInfo;
74
75 async fn on_request(
77 &self,
78 _config: &Value,
79 _head: &mut request::Parts,
80 _ctx: &mut dyn PluginContext,
81 ) -> Result<(), PluginError> {
82 Ok(())
83 }
84
85 async fn on_request_body(
87 &self,
88 _config: &Value,
89 _body: &mut Option<Bytes>,
90 _ctx: &mut dyn PluginContext,
91 ) -> Result<(), PluginError> {
92 Ok(())
93 }
94
95 async fn on_response(
97 &self,
98 _config: &Value,
99 _head: &mut response::Parts,
100 _ctx: &mut dyn PluginContext,
101 ) -> Result<(), PluginError> {
102 Ok(())
103 }
104
105 async fn on_response_body(
107 &self,
108 _config: &Value,
109 _body: &mut Option<Bytes>,
110 _ctx: &mut dyn PluginContext,
111 ) -> Result<(), PluginError> {
112 Ok(())
113 }
114
115 async fn on_logging(&self, _: &Value, _: &mut dyn PluginContext) {}
117}
118
119#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
121pub struct PluginInfo {
122 pub version: Version,
124 pub default_config: Value,
126 pub description: String,
128 pub readme: Option<String>,
130}
131
132pub fn block_on<F: Future>(f: F) -> F::Output {
137 use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
138
139 fn noop_clone(_: *const ()) -> RawWaker {
140 RawWaker::new(std::ptr::null(), &VTABLE)
141 }
142 fn noop(_: *const ()) {}
143 static VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
144
145 let raw_waker = RawWaker::new(std::ptr::null(), &VTABLE);
146 let waker = unsafe { Waker::from_raw(raw_waker) };
147 let mut cx = Context::from_waker(&waker);
148
149 let mut f = std::pin::pin!(f);
150 match f.as_mut().poll(&mut cx) {
151 Poll::Ready(val) => val,
152 Poll::Pending => panic!(
153 "plugin future returned Pending in WASM context; \
154 WASM plugins must not perform real async I/O"
155 ),
156 }
157}