Skip to main content

r2x_python/
plugin_invoker.rs

1//! Plugin invocation and execution
2
3use crate::errors::BridgeError;
4use r2x_logger as logger;
5use r2x_manifest::runtime::{build_runtime_bindings, PluginRole, RuntimeBindings};
6use r2x_manifest::types::Plugin;
7use std::time::Duration;
8
9/// Timings for a plugin invocation phase
10pub struct PluginInvocationTimings {
11    pub python_invocation: Duration,
12    pub serialization: Duration,
13}
14
15/// Result of running a plugin through the Python bridge
16pub struct PluginInvocationResult {
17    /// JSON text emitted by the plugin (may be `"null"`)
18    pub output: String,
19    /// Optional per-phase timings for diagnostics
20    pub timings: Option<PluginInvocationTimings>,
21}
22
23impl crate::python_bridge::Bridge {
24    pub fn invoke_plugin(
25        &self,
26        target: &str,
27        config_json: &str,
28        stdin_json: Option<&str>,
29        plugin_metadata: Option<&Plugin>,
30    ) -> Result<PluginInvocationResult, BridgeError> {
31        let runtime_bindings = plugin_metadata.map(build_runtime_bindings);
32
33        if let Some(bindings) = runtime_bindings.as_ref() {
34            if bindings.role == PluginRole::Upgrader {
35                logger::debug("Routing to upgrader plugin handler");
36                return self.invoke_upgrader_plugin(
37                    target,
38                    config_json,
39                    Some(bindings),
40                    plugin_metadata,
41                );
42            }
43        }
44
45        self.invoke_plugin_regular(target, config_json, stdin_json, runtime_bindings.as_ref())
46    }
47
48    pub fn invoke_plugin_with_bindings(
49        &self,
50        target: &str,
51        config_json: &str,
52        stdin_json: Option<&str>,
53        runtime_bindings: Option<&RuntimeBindings>,
54    ) -> Result<PluginInvocationResult, BridgeError> {
55        if let Some(bindings) = runtime_bindings {
56            if bindings.role == PluginRole::Upgrader {
57                logger::debug("Routing to upgrader plugin handler (runtime bindings)");
58                return self.invoke_upgrader_plugin(target, config_json, Some(bindings), None);
59            }
60        }
61
62        self.invoke_plugin_regular(target, config_json, stdin_json, runtime_bindings)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use crate::plugin_invoker::*;
69
70    #[test]
71    fn plugin_invocation_result_basics() {
72        let result = PluginInvocationResult {
73            output: String::new(),
74            timings: None,
75        };
76        assert!(result.output.is_empty());
77    }
78}