Skip to main content

phlow_runtime/
inline_module.rs

1use futures::future::BoxFuture;
2use futures::FutureExt;
3use phlow_sdk::prelude::Value;
4use phlow_sdk::structs::{ApplicationData, ModuleResponse};
5use phlow_sdk::tracing::Dispatch;
6use std::collections::HashMap;
7use std::future::Future;
8use std::sync::Arc;
9
10/// Inline module schema describing input/output shapes and input ordering.
11#[derive(Debug, Clone, Default)]
12pub struct PhlowModuleSchema {
13    /// Module input schema.
14    pub input: Value,
15    /// Module output schema.
16    pub output: Value,
17    /// Preferred input ordering.
18    pub input_order: Vec<String>,
19}
20
21impl PhlowModuleSchema {
22    /// Create an empty schema with null input/output and no ordering.
23    pub fn new() -> Self {
24        Self::default()
25    }
26
27    /// Set the input schema.
28    pub fn with_input(mut self, input: Value) -> Self {
29        self.input = input;
30        self
31    }
32
33    /// Set the output schema.
34    pub fn with_output(mut self, output: Value) -> Self {
35        self.output = output;
36        self
37    }
38
39    /// Set the input ordering used by UIs or helpers.
40    pub fn with_input_order<I, S>(mut self, input_order: I) -> Self
41    where
42        I: IntoIterator<Item = S>,
43        S: Into<String>,
44    {
45        self.input_order = input_order.into_iter().map(Into::into).collect();
46        self
47    }
48}
49
50/// Data passed to inline module handlers.
51#[derive(Clone)]
52pub struct PhlowModuleRequest {
53    /// Step input for the module invocation.
54    pub input: Option<Value>,
55    /// Previous payload when the step did not specify input.
56    pub payload: Option<Value>,
57    /// Evaluated module `with` configuration.
58    pub with: Value,
59    /// Application metadata from the pipeline.
60    pub app_data: ApplicationData,
61    /// Tracing dispatch for the runtime.
62    pub dispatch: Dispatch,
63}
64
65/// Async handler signature for inline modules.
66pub type PhlowModuleHandler =
67    Arc<dyn Fn(PhlowModuleRequest) -> BoxFuture<'static, ModuleResponse> + Send + Sync>;
68
69/// Inline module definition used by the runtime API.
70#[derive(Clone, Default)]
71pub struct PhlowModule {
72    schema: PhlowModuleSchema,
73    handler: Option<PhlowModuleHandler>,
74}
75
76impl PhlowModule {
77    /// Create a new inline module without schema or handler.
78    pub fn new() -> Self {
79        Self::default()
80    }
81
82    /// Set the schema for this module.
83    pub fn set_schema(&mut self, schema: PhlowModuleSchema) -> &mut Self {
84        self.schema = schema;
85        self
86    }
87
88    /// Set the async handler for this module.
89    pub fn set_handler<F, Fut>(&mut self, handler: F) -> &mut Self
90    where
91        F: Fn(PhlowModuleRequest) -> Fut + Send + Sync + 'static,
92        Fut: Future<Output = ModuleResponse> + Send + 'static,
93    {
94        self.handler = Some(Arc::new(move |request| handler(request).boxed()));
95        self
96    }
97
98    /// Access the schema.
99    pub fn schema(&self) -> &PhlowModuleSchema {
100        &self.schema
101    }
102
103    pub(crate) fn handler(&self) -> Option<PhlowModuleHandler> {
104        self.handler.clone()
105    }
106}
107
108/// Inline module registry keyed by module name.
109pub type InlineModules = HashMap<String, PhlowModule>;