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 bytes::Bytes;
25pub use http;
26pub use semver::Version;
27pub use serde_json;
28use serde_json::Value;
29pub use wasm_ctx::WasmHttpContext;
30#[derive(Debug)]
32pub enum PluginError {
33 ExecuteError(String),
35 NotFound(String),
37 LoadError(String),
39 SerializeError(String),
41 HttpError(String),
43}
44
45impl std::fmt::Display for PluginError {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 match self {
48 PluginError::ExecuteError(msg) => write!(f, "{}", msg),
49 PluginError::NotFound(msg) => write!(f, "{}", msg),
50 PluginError::LoadError(msg) => write!(f, "{}", msg),
51 PluginError::SerializeError(msg) => write!(f, "{}", msg),
52 PluginError::HttpError(msg) => write!(f, "{}", msg),
53 }
54 }
55}
56
57#[async_trait]
62pub trait Plugin: Send + Sync {
63 fn name(&self) -> &str;
65 fn info(&self) -> PluginInfo;
67
68 async fn on_request(
70 &self,
71 _config: &Value,
72 _head: &mut request::Parts,
73 _ctx: &mut dyn PluginContext,
74 ) -> Result<(), PluginError> {
75 Ok(())
76 }
77
78 async fn on_request_body(
80 &self,
81 _config: &Value,
82 _body: &mut Option<Bytes>,
83 _ctx: &mut dyn PluginContext,
84 ) -> Result<(), PluginError> {
85 Ok(())
86 }
87
88 async fn on_response(
90 &self,
91 _config: &Value,
92 _head: &mut response::Parts,
93 _ctx: &mut dyn PluginContext,
94 ) -> Result<(), PluginError> {
95 Ok(())
96 }
97
98 fn on_response_body(
100 &self,
101 _config: &Value,
102 _body: &mut Option<Bytes>,
103 _ctx: &mut dyn PluginContext,
104 ) -> Result<(), PluginError> {
105 Ok(())
106 }
107
108 async fn on_logging(&self, _: &Value, _: &mut dyn PluginContext) {}
110}
111
112#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
114pub struct PluginInfo {
115 pub version: Version,
117 pub default_config: Value,
119 pub description: String,
121 pub readme: Option<String>,
123}
124
125pub fn block_on<F: Future>(f: F) -> F::Output {
130 use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
131
132 fn noop_clone(_: *const ()) -> RawWaker {
133 RawWaker::new(std::ptr::null(), &VTABLE)
134 }
135 fn noop(_: *const ()) {}
136 static VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
137
138 let raw_waker = RawWaker::new(std::ptr::null(), &VTABLE);
139 let waker = unsafe { Waker::from_raw(raw_waker) };
140 let mut cx = Context::from_waker(&waker);
141
142 let mut f = std::pin::pin!(f);
143 match f.as_mut().poll(&mut cx) {
144 Poll::Ready(val) => val,
145 Poll::Pending => panic!(
146 "plugin future returned Pending in WASM context; \
147 WASM plugins must not perform real async I/O"
148 ),
149 }
150}