phlow_sdk/structs/
modules.rs

1use crate::context::Context;
2use crossbeam::channel;
3use std::collections::HashMap;
4use tokio::sync::oneshot;
5use valu3::value::Value;
6
7#[derive(Debug, Clone)]
8pub enum ModulesError {
9    ModuleNotFound(String),
10    ModuleNotLoaded(String),
11    ModuleError(String),
12}
13
14#[derive(Debug, Clone)]
15pub struct ModuleResponse {
16    pub error: Option<String>,
17    pub data: Value,
18}
19
20impl Into<ModuleResponse> for Value {
21    fn into(self) -> ModuleResponse {
22        ModuleResponse {
23            error: None,
24            data: self,
25        }
26    }
27}
28
29impl ModuleResponse {
30    pub fn from_error(error: String) -> Self {
31        Self {
32            error: Some(error),
33            data: Value::Null,
34        }
35    }
36
37    pub fn from_success(value: Value) -> Self {
38        Self {
39            error: None,
40            data: value,
41        }
42    }
43}
44
45#[derive(Debug)]
46pub struct ModulePackage {
47    pub context: Context,
48    pub sender: oneshot::Sender<ModuleResponse>,
49}
50
51impl ModulePackage {
52    pub fn input(&self) -> Option<Value> {
53        self.context.input.clone()
54    }
55}
56
57#[derive(Debug, Default, Clone)]
58pub struct Modules {
59    pub modules: HashMap<String, channel::Sender<ModulePackage>>,
60}
61
62impl Modules {
63    pub fn extract(&self) -> Self {
64        Self {
65            modules: self.modules.clone(),
66        }
67    }
68
69    pub fn register(&mut self, name: &str, sender: channel::Sender<ModulePackage>) {
70        self.modules.insert(name.to_string(), sender);
71    }
72
73    pub async fn execute(
74        &self,
75        name: &str,
76        context: &Context,
77    ) -> Result<ModuleResponse, ModulesError> {
78        if let Some(module_sender) = self.modules.get(name) {
79            let (package_sender, package_receiver) = oneshot::channel();
80            let package = ModulePackage {
81                context: context.clone(),
82                sender: package_sender,
83            };
84
85            let _ = module_sender.send(package);
86
87            let value = package_receiver.await.unwrap_or(ModuleResponse::from_error(
88                "Module response channel closed".to_string(),
89            ));
90
91            Ok(value)
92        } else {
93            Err(ModulesError::ModuleNotLoaded(name.to_string()))
94        }
95    }
96}