use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use serde_json::Value;
use log::warn;
use crate::error::{Result};
pub type SharedState = HashMap<String, Value>;
pub type Action = Option<String>;
#[derive(Clone)]
pub struct BaseNode {
params: Arc<RwLock<HashMap<String, Value>>>,
successors: Arc<RwLock<HashMap<String, Arc<dyn Node>>>>,
}
pub trait Node: Send + Sync + 'static {
fn params(&self) -> Arc<RwLock<HashMap<String, Value>>>;
fn successors(&self) -> Arc<RwLock<HashMap<String, Arc<dyn Node>>>>;
fn set_params(&self, params: HashMap<String, Value>);
fn add_successor(&self, node: Arc<dyn Node>, action: &str) -> Result<Arc<dyn Node>>;
fn prep(&self, _shared: &mut SharedState) -> Result<Value> {
Ok(Value::Null)
}
fn exec(&self, _prep_res: Value) -> Result<Value> {
Ok(Value::Null)
}
fn post(&self, _shared: &mut SharedState, _prep_res: Value, _exec_res: Value) -> Result<Action> {
Ok(None) }
fn _exec(&self, prep_res: Value) -> Result<Value> {
self.exec(prep_res)
}
fn _run(&self, shared: &mut SharedState) -> Result<Action> {
let prep_res = self.prep(shared)?;
let exec_res = self._exec(prep_res.clone())?;
self.post(shared, prep_res, exec_res)
}
fn run(&self, shared: &mut SharedState) -> Result<Action> {
let successors_lock = self.successors();
let successors = successors_lock.read().unwrap();
if !successors.is_empty() {
warn!("Node won't run successors. Use Flow.");
}
self._run(shared)
}
}
impl BaseNode {
pub fn new() -> Self {
Self {
params: Arc::new(RwLock::new(HashMap::new())),
successors: Arc::new(RwLock::new(HashMap::new())),
}
}
}
impl Default for BaseNode {
fn default() -> Self {
Self::new()
}
}
impl Node for BaseNode {
fn params(&self) -> Arc<RwLock<HashMap<String, Value>>> {
self.params.clone()
}
fn successors(&self) -> Arc<RwLock<HashMap<String, Arc<dyn Node>>>> {
self.successors.clone()
}
fn set_params(&self, params: HashMap<String, Value>) {
let params_lock = self.params();
let mut p = params_lock.write().unwrap();
*p = params;
}
fn add_successor(&self, node: Arc<dyn Node>, action: &str) -> Result<Arc<dyn Node>> {
let successors_lock = self.successors();
let mut successors = successors_lock.write().unwrap();
if successors.contains_key(action) {
warn!("Overwriting successor for action '{}'", action);
}
successors.insert(action.to_string(), node.clone());
Ok(node)
}
}