|
|
|
@@ -1,140 +1,384 @@
|
|
|
|
|
use rhai::{Dynamic, Engine, EvalAltResult, NativeCallContext, Position};
|
|
|
|
|
use rhai::plugin::*;
|
|
|
|
|
use rhai::{Engine, EvalAltResult, Position, Module, INT, Dynamic, Array};
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
use std::mem;
|
|
|
|
|
|
|
|
|
|
use heromodels_core::BaseModelData;
|
|
|
|
|
use crate::db::hero::OurDB; // Import OurDB for actual DB operations
|
|
|
|
|
use crate::db::Collection; // Collection might be needed if we add more specific DB functions
|
|
|
|
|
use super::{
|
|
|
|
|
flow::Flow,
|
|
|
|
|
flow_step::FlowStep,
|
|
|
|
|
signature_requirement::SignatureRequirement,
|
|
|
|
|
};
|
|
|
|
|
// use rhai_wrapper::wrap_vec_return; // Not currently used for flow, but keep for potential future use.
|
|
|
|
|
use super::flow::Flow;
|
|
|
|
|
use super::flow_step::FlowStep;
|
|
|
|
|
use super::signature_requirement::SignatureRequirement;
|
|
|
|
|
type RhaiFlow = Flow;
|
|
|
|
|
type RhaiFlowStep = FlowStep;
|
|
|
|
|
type RhaiSignatureRequirement = SignatureRequirement;
|
|
|
|
|
use crate::db::hero::OurDB;
|
|
|
|
|
use crate::db::Collection;
|
|
|
|
|
use crate::db::Db;
|
|
|
|
|
use heromodels_core::Model;
|
|
|
|
|
|
|
|
|
|
// Helper function to convert Rhai's i64 to u32 for IDs
|
|
|
|
|
fn i64_to_u32(val: i64, context_pos: Position, field_name: &str, object_name: &str) -> Result<u32, Box<EvalAltResult>> {
|
|
|
|
|
val.try_into().map_err(|_e| {
|
|
|
|
|
// Helper to convert i64 from Rhai to u32 for IDs
|
|
|
|
|
fn id_from_i64_to_u32(id_i64: i64) -> Result<u32, Box<EvalAltResult>> {
|
|
|
|
|
u32::try_from(id_i64).map_err(|_|
|
|
|
|
|
Box::new(EvalAltResult::ErrorArithmetic(
|
|
|
|
|
format!("Conversion error for {} in {} from i64 to u32", field_name, object_name),
|
|
|
|
|
context_pos,
|
|
|
|
|
format!("Failed to convert ID '{}' to u32", id_i64).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
))
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper to convert i64 from Rhai to u64 for timestamps or other large numbers
|
|
|
|
|
fn val_from_i64_to_u64(val_i64: i64) -> Result<u64, Box<EvalAltResult>> {
|
|
|
|
|
u64::try_from(val_i64).map_err(|_|
|
|
|
|
|
Box::new(EvalAltResult::ErrorArithmetic(
|
|
|
|
|
format!("Failed to convert value '{}' to u64", val_i64).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
))
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[export_module]
|
|
|
|
|
mod rhai_flow_module {
|
|
|
|
|
// --- Flow Functions ---
|
|
|
|
|
#[rhai_fn(name = "new_flow")]
|
|
|
|
|
pub fn new_flow(flow_uuid: String) -> RhaiFlow {
|
|
|
|
|
Flow::new(flow_uuid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the flow name
|
|
|
|
|
#[rhai_fn(name = "name", return_raw, global, pure)]
|
|
|
|
|
pub fn flow_name(flow: &mut RhaiFlow, name: String) -> Result<RhaiFlow, Box<EvalAltResult>> {
|
|
|
|
|
let owned_flow = mem::replace(flow, Flow::new("")); // Dummy for replacement
|
|
|
|
|
*flow = owned_flow.name(name);
|
|
|
|
|
Ok(flow.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the flow status
|
|
|
|
|
#[rhai_fn(name = "status", return_raw, global, pure)]
|
|
|
|
|
pub fn flow_status(flow: &mut RhaiFlow, status: String) -> Result<RhaiFlow, Box<EvalAltResult>> {
|
|
|
|
|
let owned_flow = mem::replace(flow, Flow::new("")); // Dummy for replacement
|
|
|
|
|
*flow = owned_flow.status(status);
|
|
|
|
|
Ok(flow.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Adds a step to the flow
|
|
|
|
|
#[rhai_fn(name = "add_step", return_raw, global, pure)]
|
|
|
|
|
pub fn flow_add_step(flow: &mut RhaiFlow, step: RhaiFlowStep) -> Result<RhaiFlow, Box<EvalAltResult>> {
|
|
|
|
|
let owned_flow = mem::replace(flow, Flow::new("")); // Dummy for replacement
|
|
|
|
|
*flow = owned_flow.add_step(step);
|
|
|
|
|
Ok(flow.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flow Getters
|
|
|
|
|
#[rhai_fn(get = "id", pure)]
|
|
|
|
|
pub fn get_id(flow: &mut RhaiFlow) -> i64 { flow.base_data.id as i64 }
|
|
|
|
|
#[rhai_fn(get = "created_at", pure)]
|
|
|
|
|
pub fn get_created_at(flow: &mut RhaiFlow) -> i64 { flow.base_data.created_at }
|
|
|
|
|
#[rhai_fn(get = "modified_at", pure)]
|
|
|
|
|
pub fn get_modified_at(flow: &mut RhaiFlow) -> i64 { flow.base_data.modified_at }
|
|
|
|
|
#[rhai_fn(get = "flow_uuid", pure)]
|
|
|
|
|
pub fn get_flow_uuid(flow: &mut RhaiFlow) -> String { flow.flow_uuid.clone() }
|
|
|
|
|
#[rhai_fn(get = "name", pure)]
|
|
|
|
|
pub fn get_name(flow: &mut RhaiFlow) -> String { flow.name.clone() }
|
|
|
|
|
#[rhai_fn(get = "status", pure)]
|
|
|
|
|
pub fn get_status(flow: &mut RhaiFlow) -> String { flow.status.clone() }
|
|
|
|
|
#[rhai_fn(get = "steps", pure)]
|
|
|
|
|
pub fn get_steps(flow: &mut RhaiFlow) -> Array {
|
|
|
|
|
flow.steps.iter().cloned().map(Dynamic::from).collect::<Array>()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- FlowStep Functions ---
|
|
|
|
|
#[rhai_fn(global)]
|
|
|
|
|
pub fn new_flow_step(step_order_i64: i64) -> Dynamic {
|
|
|
|
|
match id_from_i64_to_u32(step_order_i64) {
|
|
|
|
|
Ok(step_order) => {
|
|
|
|
|
let mut flow_step = FlowStep::default();
|
|
|
|
|
flow_step.step_order = step_order;
|
|
|
|
|
Dynamic::from(flow_step)
|
|
|
|
|
},
|
|
|
|
|
Err(err) => Dynamic::from(err.to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the flow step description
|
|
|
|
|
#[rhai_fn(name = "description", return_raw, global, pure)]
|
|
|
|
|
pub fn flow_step_description(step: &mut RhaiFlowStep, description: String) -> Result<RhaiFlowStep, Box<EvalAltResult>> {
|
|
|
|
|
let owned_step = mem::replace(step, FlowStep::default()); // Use Default trait
|
|
|
|
|
*step = owned_step.description(description);
|
|
|
|
|
Ok(step.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the flow step status
|
|
|
|
|
#[rhai_fn(name = "status", return_raw, global, pure)]
|
|
|
|
|
pub fn flow_step_status(step: &mut RhaiFlowStep, status: String) -> Result<RhaiFlowStep, Box<EvalAltResult>> {
|
|
|
|
|
let owned_step = mem::replace(step, FlowStep::default()); // Use Default trait
|
|
|
|
|
*step = owned_step.status(status);
|
|
|
|
|
Ok(step.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FlowStep Getters
|
|
|
|
|
#[rhai_fn(get = "id", pure)]
|
|
|
|
|
pub fn get_step_id(step: &mut RhaiFlowStep) -> i64 { step.base_data.id as i64 }
|
|
|
|
|
#[rhai_fn(get = "created_at", pure)]
|
|
|
|
|
pub fn get_step_created_at(step: &mut RhaiFlowStep) -> i64 { step.base_data.created_at }
|
|
|
|
|
#[rhai_fn(get = "modified_at", pure)]
|
|
|
|
|
pub fn get_step_modified_at(step: &mut RhaiFlowStep) -> i64 { step.base_data.modified_at }
|
|
|
|
|
#[rhai_fn(get = "description", pure)]
|
|
|
|
|
pub fn get_step_description(step: &mut RhaiFlowStep) -> Dynamic {
|
|
|
|
|
match &step.description {
|
|
|
|
|
Some(desc) => Dynamic::from(desc.clone()),
|
|
|
|
|
None => Dynamic::UNIT,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#[rhai_fn(get = "step_order", pure)]
|
|
|
|
|
pub fn get_step_order(step: &mut RhaiFlowStep) -> i64 { step.step_order as i64 }
|
|
|
|
|
#[rhai_fn(get = "status", pure)]
|
|
|
|
|
pub fn get_step_status(step: &mut RhaiFlowStep) -> String { step.status.clone() }
|
|
|
|
|
|
|
|
|
|
// --- SignatureRequirement Functions ---
|
|
|
|
|
/// Create a new signature requirement
|
|
|
|
|
#[rhai_fn(global)]
|
|
|
|
|
pub fn new_signature_requirement(flow_step_id_i64: i64, public_key: String, message: String) -> Dynamic {
|
|
|
|
|
match id_from_i64_to_u32(flow_step_id_i64) {
|
|
|
|
|
Ok(flow_step_id) => {
|
|
|
|
|
let mut signature_requirement = SignatureRequirement::default();
|
|
|
|
|
signature_requirement.flow_step_id = flow_step_id;
|
|
|
|
|
signature_requirement.public_key = public_key;
|
|
|
|
|
signature_requirement.message = message;
|
|
|
|
|
Dynamic::from(signature_requirement)
|
|
|
|
|
},
|
|
|
|
|
Err(err) => Dynamic::from(err.to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the signed_by field
|
|
|
|
|
#[rhai_fn(name = "signed_by", return_raw, global, pure)]
|
|
|
|
|
pub fn signature_requirement_signed_by(sr: &mut RhaiSignatureRequirement, signed_by: String) -> Result<RhaiSignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
let owned_sr = mem::replace(sr, SignatureRequirement::default()); // Use Default trait
|
|
|
|
|
*sr = owned_sr.signed_by(signed_by);
|
|
|
|
|
Ok(sr.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the signature field
|
|
|
|
|
#[rhai_fn(name = "signature", return_raw, global, pure)]
|
|
|
|
|
pub fn signature_requirement_signature(sr: &mut RhaiSignatureRequirement, signature: String) -> Result<RhaiSignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
let owned_sr = mem::replace(sr, SignatureRequirement::default()); // Use Default trait
|
|
|
|
|
*sr = owned_sr.signature(signature);
|
|
|
|
|
Ok(sr.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Sets the status field
|
|
|
|
|
#[rhai_fn(name = "status", return_raw, global, pure)]
|
|
|
|
|
pub fn signature_requirement_status(sr: &mut RhaiSignatureRequirement, status: String) -> Result<RhaiSignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
let owned_sr = mem::replace(sr, SignatureRequirement::default()); // Use Default trait
|
|
|
|
|
*sr = owned_sr.status(status);
|
|
|
|
|
Ok(sr.clone())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SignatureRequirement Getters
|
|
|
|
|
#[rhai_fn(get = "id", pure)]
|
|
|
|
|
pub fn get_sr_id(sr: &mut RhaiSignatureRequirement) -> i64 { sr.base_data.id as i64 }
|
|
|
|
|
#[rhai_fn(get = "created_at", pure)]
|
|
|
|
|
pub fn get_sr_created_at(sr: &mut RhaiSignatureRequirement) -> i64 { sr.base_data.created_at }
|
|
|
|
|
#[rhai_fn(get = "modified_at", pure)]
|
|
|
|
|
pub fn get_sr_modified_at(sr: &mut RhaiSignatureRequirement) -> i64 { sr.base_data.modified_at }
|
|
|
|
|
#[rhai_fn(get = "flow_step_id", pure)]
|
|
|
|
|
pub fn get_sr_flow_step_id(sr: &mut RhaiSignatureRequirement) -> i64 { sr.flow_step_id as i64 }
|
|
|
|
|
#[rhai_fn(get = "public_key", pure)]
|
|
|
|
|
pub fn get_sr_public_key(sr: &mut RhaiSignatureRequirement) -> String { sr.public_key.clone() }
|
|
|
|
|
#[rhai_fn(get = "message", pure)]
|
|
|
|
|
pub fn get_sr_message(sr: &mut RhaiSignatureRequirement) -> String { sr.message.clone() }
|
|
|
|
|
#[rhai_fn(get = "signed_by", pure)]
|
|
|
|
|
pub fn get_sr_signed_by(sr: &mut RhaiSignatureRequirement) -> Dynamic {
|
|
|
|
|
match &sr.signed_by {
|
|
|
|
|
Some(signed_by) => Dynamic::from(signed_by.clone()),
|
|
|
|
|
None => Dynamic::UNIT,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#[rhai_fn(get = "signature", pure)]
|
|
|
|
|
pub fn get_sr_signature(sr: &mut RhaiSignatureRequirement) -> Dynamic {
|
|
|
|
|
match &sr.signature {
|
|
|
|
|
Some(signature) => Dynamic::from(signature.clone()),
|
|
|
|
|
None => Dynamic::UNIT,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#[rhai_fn(get = "status", pure)]
|
|
|
|
|
pub fn get_sr_status(sr: &mut RhaiSignatureRequirement) -> String { sr.status.clone() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Register the flow module with the Rhai engine
|
|
|
|
|
pub fn register_flow_rhai_module(engine: &mut Engine, db: Arc<OurDB>) {
|
|
|
|
|
// --- Flow Model ---
|
|
|
|
|
|
|
|
|
|
// Constructor: new_flow(id: u32, flow_uuid: String)
|
|
|
|
|
engine.register_fn("new_flow", move |context: NativeCallContext, id_i64: i64, flow_uuid: String| -> Result<Flow, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = i64_to_u32(id_i64, context.position(), "id", "new_flow")?;
|
|
|
|
|
Ok(Flow::new(id_u32, flow_uuid))
|
|
|
|
|
// Create a module for database functions
|
|
|
|
|
let mut db_module = Module::new();
|
|
|
|
|
|
|
|
|
|
// Flow database functions
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("save_flow", move |flow: Flow| -> Result<Flow, Box<EvalAltResult>> {
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
let result = db_clone.set(&flow)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error save_flow: {:?}", e).into(), Position::NONE)))?;
|
|
|
|
|
|
|
|
|
|
// Return the updated flow with the correct ID
|
|
|
|
|
Ok(result.1)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Builder methods for Flow
|
|
|
|
|
engine.register_fn("name", |flow: Flow, name_val: String| -> Flow { flow.name(name_val) });
|
|
|
|
|
engine.register_fn("status", |flow: Flow, status_val: String| -> Flow { flow.status(status_val) });
|
|
|
|
|
engine.register_fn("add_step", |flow: Flow, step: FlowStep| -> Flow { flow.add_step(step) });
|
|
|
|
|
|
|
|
|
|
// Getters for Flow fields
|
|
|
|
|
engine.register_get("id", |flow: &mut Flow| -> Result<i64, Box<EvalAltResult>> { Ok(flow.base_data.id as i64) });
|
|
|
|
|
engine.register_get("base_data", |flow: &mut Flow| -> Result<BaseModelData, Box<EvalAltResult>> { Ok(flow.base_data.clone()) });
|
|
|
|
|
engine.register_get("flow_uuid", |flow: &mut Flow| -> Result<String, Box<EvalAltResult>> { Ok(flow.flow_uuid.clone()) });
|
|
|
|
|
engine.register_get("name", |flow: &mut Flow| -> Result<String, Box<EvalAltResult>> { Ok(flow.name.clone()) });
|
|
|
|
|
engine.register_get("status", |flow: &mut Flow| -> Result<String, Box<EvalAltResult>> { Ok(flow.status.clone()) });
|
|
|
|
|
engine.register_get("steps", |flow: &mut Flow| -> Result<rhai::Array, Box<EvalAltResult>> {
|
|
|
|
|
let rhai_array = flow.steps.iter().cloned().map(Dynamic::from).collect::<rhai::Array>();
|
|
|
|
|
Ok(rhai_array)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// --- FlowStep Model ---
|
|
|
|
|
|
|
|
|
|
// Constructor: new_flow_step(id: u32, step_order: u32)
|
|
|
|
|
engine.register_fn("new_flow_step", move |context: NativeCallContext, id_i64: i64, step_order_i64: i64| -> Result<FlowStep, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = i64_to_u32(id_i64, context.position(), "id", "new_flow_step")?;
|
|
|
|
|
let step_order_u32 = i64_to_u32(step_order_i64, context.position(), "step_order", "new_flow_step")?;
|
|
|
|
|
Ok(FlowStep::new(id_u32, step_order_u32))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Builder methods for FlowStep
|
|
|
|
|
engine.register_fn("description", |fs: FlowStep, desc_val: String| -> FlowStep { fs.description(desc_val) }); // Assuming FlowStep::description takes impl ToString
|
|
|
|
|
engine.register_fn("status", |fs: FlowStep, status_val: String| -> FlowStep { fs.status(status_val) });
|
|
|
|
|
|
|
|
|
|
// Getters for FlowStep fields
|
|
|
|
|
engine.register_get("id", |step: &mut FlowStep| -> Result<i64, Box<EvalAltResult>> { Ok(step.base_data.id as i64) });
|
|
|
|
|
engine.register_get("base_data", |step: &mut FlowStep| -> Result<BaseModelData, Box<EvalAltResult>> { Ok(step.base_data.clone()) });
|
|
|
|
|
engine.register_get("description", |step: &mut FlowStep| -> Result<Dynamic, Box<EvalAltResult>> { Ok(match step.description.clone() { Some(s) => Dynamic::from(s), None => Dynamic::from(()) }) });
|
|
|
|
|
engine.register_get("step_order", |step: &mut FlowStep| -> Result<i64, Box<EvalAltResult>> { Ok(step.step_order as i64) });
|
|
|
|
|
engine.register_get("status", |step: &mut FlowStep| -> Result<String, Box<EvalAltResult>> { Ok(step.status.clone()) });
|
|
|
|
|
|
|
|
|
|
// --- SignatureRequirement Model ---
|
|
|
|
|
|
|
|
|
|
// Constructor: new_signature_requirement(id: u32, flow_step_id: u32, public_key: String, message: String)
|
|
|
|
|
engine.register_fn("new_signature_requirement",
|
|
|
|
|
move |context: NativeCallContext, id_i64: i64, flow_step_id_i64: i64, public_key: String, message: String|
|
|
|
|
|
-> Result<SignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = i64_to_u32(id_i64, context.position(), "id", "new_signature_requirement")?;
|
|
|
|
|
let flow_step_id_u32 = i64_to_u32(flow_step_id_i64, context.position(), "flow_step_id", "new_signature_requirement")?;
|
|
|
|
|
Ok(SignatureRequirement::new(id_u32, flow_step_id_u32, public_key, message))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Builder methods for SignatureRequirement
|
|
|
|
|
engine.register_fn("signed_by", |sr: SignatureRequirement, signed_by_val: String| -> SignatureRequirement { sr.signed_by(signed_by_val) }); // Assuming SR::signed_by takes impl ToString
|
|
|
|
|
engine.register_fn("signature", |sr: SignatureRequirement, sig_val: String| -> SignatureRequirement { sr.signature(sig_val) }); // Assuming SR::signature takes impl ToString
|
|
|
|
|
engine.register_fn("status", |sr: SignatureRequirement, status_val: String| -> SignatureRequirement { sr.status(status_val) });
|
|
|
|
|
|
|
|
|
|
// Getters for SignatureRequirement fields
|
|
|
|
|
engine.register_get("id", |sr: &mut SignatureRequirement| -> Result<i64, Box<EvalAltResult>> { Ok(sr.base_data.id as i64) });
|
|
|
|
|
engine.register_get("base_data", |sr: &mut SignatureRequirement| -> Result<BaseModelData, Box<EvalAltResult>> { Ok(sr.base_data.clone()) });
|
|
|
|
|
engine.register_get("flow_step_id", |sr: &mut SignatureRequirement| -> Result<i64, Box<EvalAltResult>> { Ok(sr.flow_step_id as i64) });
|
|
|
|
|
engine.register_get("public_key", |sr: &mut SignatureRequirement| -> Result<String, Box<EvalAltResult>> { Ok(sr.public_key.clone()) });
|
|
|
|
|
engine.register_get("message", |sr: &mut SignatureRequirement| -> Result<String, Box<EvalAltResult>> { Ok(sr.message.clone()) });
|
|
|
|
|
engine.register_get("signed_by", |sr: &mut SignatureRequirement| -> Result<Dynamic, Box<EvalAltResult>> { Ok(match sr.signed_by.clone() { Some(s) => Dynamic::from(s), None => Dynamic::from(()) }) });
|
|
|
|
|
engine.register_get("signature", |sr: &mut SignatureRequirement| -> Result<Dynamic, Box<EvalAltResult>> { Ok(match sr.signature.clone() { Some(s) => Dynamic::from(s), None => Dynamic::from(()) }) });
|
|
|
|
|
engine.register_get("status", |sr: &mut SignatureRequirement| -> Result<String, Box<EvalAltResult>> { Ok(sr.status.clone()) });
|
|
|
|
|
|
|
|
|
|
// --- BaseModelData Getters (if not already globally registered) ---
|
|
|
|
|
// Assuming these might be specific to the context or shadowed, explicit registration is safer.
|
|
|
|
|
engine.register_get("id", |bmd: &mut BaseModelData| -> Result<i64, Box<EvalAltResult>> { Ok(bmd.id as i64) });
|
|
|
|
|
engine.register_get("created_at", |bmd: &mut BaseModelData| -> Result<i64, Box<EvalAltResult>> { Ok(bmd.created_at) });
|
|
|
|
|
engine.register_get("modified_at", |bmd: &mut BaseModelData| -> Result<i64, Box<EvalAltResult>> { Ok(bmd.modified_at) });
|
|
|
|
|
// engine.register_get("comments", |bmd: &mut BaseModelData| Ok(bmd.comments.clone())); // Rhai might need specific handling for Vec<String>
|
|
|
|
|
|
|
|
|
|
// --- Database Interaction Functions ---
|
|
|
|
|
|
|
|
|
|
let captured_db_for_set_flow = Arc::clone(&db);
|
|
|
|
|
engine.register_fn("set_flow", move |flow: Flow| -> Result<(), Box<EvalAltResult>> {
|
|
|
|
|
captured_db_for_set_flow.set(&flow).map(|_| ()).map_err(|e| {
|
|
|
|
|
Box::new(EvalAltResult::ErrorRuntime(format!("Failed to set Flow (ID: {}): {}", flow.base_data.id, e).into(), Position::NONE))
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let captured_db_for_get_flow = Arc::clone(&db);
|
|
|
|
|
engine.register_fn("get_flow_by_id", move |context: NativeCallContext, id_i64: i64| -> Result<Flow, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = i64_to_u32(id_i64, context.position(), "id", "get_flow_by_id")?;
|
|
|
|
|
captured_db_for_get_flow.get_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("Error getting Flow (ID: {}): {}", id_u32, e).into(), Position::NONE)))?
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("get_flow_by_id", move |id_i64: INT| -> Result<Flow, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
db_clone.get_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_flow_by_id: {:?}", e).into(), Position::NONE)))?
|
|
|
|
|
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("Flow with ID {} not found", id_u32).into(), Position::NONE)))
|
|
|
|
|
});
|
|
|
|
|
// Add get_flows_by_uuid, flow_exists etc. as needed, using wrap_vec_return for Vec results.
|
|
|
|
|
|
|
|
|
|
// FlowStep DB functions are removed as FlowSteps are now part of Flow.
|
|
|
|
|
|
|
|
|
|
let captured_db_for_set_sig_req = Arc::clone(&db);
|
|
|
|
|
engine.register_fn("set_signature_requirement", move |sr: SignatureRequirement| -> Result<(), Box<EvalAltResult>> {
|
|
|
|
|
captured_db_for_set_sig_req.set(&sr).map(|_| ()).map_err(|e| {
|
|
|
|
|
Box::new(EvalAltResult::ErrorRuntime(format!("Failed to set SignatureRequirement (ID: {}): {}", sr.base_data.id, e).into(), Position::NONE))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("delete_flow", move |id_i64: INT| -> Result<(), Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
let collection = db_clone.collection::<Flow>()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get flow collection: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
collection.delete_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to delete Flow (ID: {}): {:?}", id_u32, e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let captured_db_for_get_sig_req = Arc::clone(&db);
|
|
|
|
|
engine.register_fn("get_signature_requirement_by_id",
|
|
|
|
|
move |context: NativeCallContext, id_i64: i64|
|
|
|
|
|
-> Result<SignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = i64_to_u32(id_i64, context.position(), "id", "get_signature_requirement_by_id")?;
|
|
|
|
|
captured_db_for_get_sig_req.get_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("Error getting SignatureRequirement (ID: {}): {}", id_u32, e).into(), Position::NONE)))?
|
|
|
|
|
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("SignatureRequirement with ID {} not found", id_u32).into(), Position::NONE)))
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("list_flows", move || -> Result<Dynamic, Box<EvalAltResult>> {
|
|
|
|
|
let collection = db_clone.collection::<Flow>()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get flow collection: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
let flows = collection.get_all()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get all flows: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
let mut array = Array::new();
|
|
|
|
|
for flow in flows {
|
|
|
|
|
array.push(Dynamic::from(flow));
|
|
|
|
|
}
|
|
|
|
|
Ok(Dynamic::from(array))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FlowStep database functions
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("save_flow_step", move |step: FlowStep| -> Result<FlowStep, Box<EvalAltResult>> {
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
let result = db_clone.set(&step)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error save_flow_step: {:?}", e).into(), Position::NONE)))?;
|
|
|
|
|
|
|
|
|
|
// Return the updated flow step with the correct ID
|
|
|
|
|
Ok(result.1)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("get_flow_step_by_id", move |id_i64: INT| -> Result<FlowStep, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
db_clone.get_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_flow_step_by_id: {:?}", e).into(), Position::NONE)))?
|
|
|
|
|
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("FlowStep with ID {} not found", id_u32).into(), Position::NONE)))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("delete_flow_step", move |id_i64: INT| -> Result<(), Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
let collection = db_clone.collection::<FlowStep>()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get flow step collection: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
collection.delete_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to delete FlowStep (ID: {}): {:?}", id_u32, e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("list_flow_steps", move || -> Result<Dynamic, Box<EvalAltResult>> {
|
|
|
|
|
let collection = db_clone.collection::<FlowStep>()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get flow step collection: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
let steps = collection.get_all()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get all flow steps: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
let mut array = Array::new();
|
|
|
|
|
for step in steps {
|
|
|
|
|
array.push(Dynamic::from(step));
|
|
|
|
|
}
|
|
|
|
|
Ok(Dynamic::from(array))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// SignatureRequirement database functions
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("save_signature_requirement", move |sr: SignatureRequirement| -> Result<SignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
let result = db_clone.set(&sr)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error save_signature_requirement: {:?}", e).into(), Position::NONE)))?;
|
|
|
|
|
|
|
|
|
|
// Return the updated signature requirement with the correct ID
|
|
|
|
|
Ok(result.1)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("get_signature_requirement_by_id", move |id_i64: INT| -> Result<SignatureRequirement, Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
db_clone.get_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(format!("DB Error get_signature_requirement_by_id: {:?}", e).into(), Position::NONE)))?
|
|
|
|
|
.ok_or_else(|| Box::new(EvalAltResult::ErrorRuntime(format!("SignatureRequirement with ID {} not found", id_u32).into(), Position::NONE)))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("delete_signature_requirement", move |id_i64: INT| -> Result<(), Box<EvalAltResult>> {
|
|
|
|
|
let id_u32 = id_from_i64_to_u32(id_i64)?;
|
|
|
|
|
// Use the Collection trait method directly
|
|
|
|
|
let collection = db_clone.collection::<SignatureRequirement>()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get signature requirement collection: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
collection.delete_by_id(id_u32)
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to delete SignatureRequirement (ID: {}): {:?}", id_u32, e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let db_clone = Arc::clone(&db);
|
|
|
|
|
db_module.set_native_fn("list_signature_requirements", move || -> Result<Dynamic, Box<EvalAltResult>> {
|
|
|
|
|
let collection = db_clone.collection::<SignatureRequirement>()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get signature requirement collection: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
let srs = collection.get_all()
|
|
|
|
|
.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(
|
|
|
|
|
format!("Failed to get all signature requirements: {:?}", e).into(),
|
|
|
|
|
Position::NONE
|
|
|
|
|
)))?;
|
|
|
|
|
let mut array = Array::new();
|
|
|
|
|
for sr in srs {
|
|
|
|
|
array.push(Dynamic::from(sr));
|
|
|
|
|
}
|
|
|
|
|
Ok(Dynamic::from(array))
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Register the database module globally
|
|
|
|
|
engine.register_static_module("db", db_module.into());
|
|
|
|
|
|
|
|
|
|
// Register the flow module using exported_module! macro
|
|
|
|
|
let module = exported_module!(rhai_flow_module);
|
|
|
|
|
engine.register_global_module(module.into());
|
|
|
|
|
|
|
|
|
|
println!("Flow Rhai module registered.");
|
|
|
|
|
}
|
|
|
|
|