Skip to main content

folk_api/
executor.rs

1//! The `Executor` trait — how plugins send work to PHP workers.
2//!
3//! `folk-core` provides the concrete implementation, backed by the worker pool.
4
5use std::sync::Arc;
6
7use anyhow::Result;
8use async_trait::async_trait;
9use bytes::Bytes;
10
11/// Sends a serialized payload to a PHP worker and returns the response.
12///
13/// Plugins call this; they never see the worker pool directly.
14#[async_trait]
15pub trait Executor: Send + Sync + 'static {
16    /// Send `payload` to a worker and return the response bytes.
17    /// Uses the RPC method name "dispatch" by default.
18    async fn execute(&self, payload: Bytes) -> Result<Bytes> {
19        self.execute_method("dispatch", payload).await
20    }
21
22    /// Send `payload` to a worker using a specific RPC method name.
23    async fn execute_method(&self, method: &str, payload: Bytes) -> Result<Bytes>;
24
25    /// Send structured data directly (no serialization).
26    ///
27    /// The default implementation falls back to JSON serialization
28    /// via [`execute_method`]. Extension runtimes override this to
29    /// pass values through the channel without JSON encode/decode.
30    async fn execute_value(
31        &self,
32        method: &str,
33        payload: serde_json::Value,
34    ) -> Result<serde_json::Value> {
35        let bytes = serde_json::to_vec(&payload)?;
36        let result = self.execute_method(method, Bytes::from(bytes)).await?;
37        Ok(serde_json::from_slice(&result)?)
38    }
39}
40
41/// Blanket impl: an `Arc<dyn Executor>` is also an `Executor`.
42#[async_trait]
43impl<T: Executor + ?Sized> Executor for Arc<T> {
44    async fn execute_method(&self, method: &str, payload: Bytes) -> Result<Bytes> {
45        (**self).execute_method(method, payload).await
46    }
47
48    async fn execute_value(
49        &self,
50        method: &str,
51        payload: serde_json::Value,
52    ) -> Result<serde_json::Value> {
53        (**self).execute_value(method, payload).await
54    }
55}