use std::path::Path; use rhai::{Scope}; use heromodels::models::flow::{Flow, FlowStep, SignatureRequirement}; use engine::{create_heromodels_engine, eval_file}; use engine::mock_db::{create_mock_db, seed_mock_db}; use heromodels_core::Model; fn main() -> Result<(), Box> { println!("Flow Rhai Example"); println!("================="); // Create a mock database let db = create_mock_db(); // Seed the database with initial data seed_mock_db(db.clone()); // Create the Rhai engine with all modules registered let engine = create_heromodels_engine(db.clone()); // Get the path to the script let script_path = Path::new(file!()) .parent() .unwrap() .join("flow_script.rhai"); println!("\nRunning script: {}", script_path.display()); println!("---------------------"); // Run the script match eval_file(&engine, &script_path.to_string_lossy()) { Ok(result) => { if !result.is_unit() { println!("\nScript returned: {:?}", result); } println!("\nScript executed successfully!"); }, Err(err) => { eprintln!("\nError running script: {}", err); return Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, err.to_string()))); } } // Demonstrate direct Rust interaction with the Rhai-exposed flow functionality println!("\nDirect Rust interaction with Rhai-exposed flow functionality"); println!("----------------------------------------------------------"); // Create a new scope let mut scope = Scope::new(); // Create a new flow using the Rhai function let result = engine.eval::("new_flow(0, \"Direct Rust Flow\")"); match result { Ok(mut flow) => { println!("Created flow from Rust: {} (ID: {})", flow.name, flow.get_id()); // Set flow status using the builder pattern flow = flow.status("active".to_string()); println!("Set flow status to: {}", flow.status); // Create a new flow step using the Rhai function let result = engine.eval::("new_flow_step(0, 1)"); match result { Ok(mut step) => { println!("Created flow step from Rust: Step Order {} (ID: {})", step.step_order, step.get_id()); // Set step description step = step.description("Direct Rust Step".to_string()); println!("Set step description to: {}", step.description.clone().unwrap_or_else(|| "None".to_string())); // Create a signature requirement using the Rhai function let result = engine.eval::( "new_signature_requirement(0, 1, \"Direct Rust Signer\", \"Please sign this document\")" ); match result { Ok(req) => { println!("Created signature requirement from Rust: Public Key {} (ID: {})", req.public_key, req.get_id()); // Add the step to the flow using the builder pattern flow = flow.add_step(step); println!("Added step to flow. Flow now has {} steps", flow.steps.len()); // Save the flow to the database using the Rhai function let save_flow_script = "fn save_it(f) { return db::save_flow(f); }"; let save_flow_ast = engine.compile(save_flow_script).unwrap(); let result = engine.call_fn::(&mut scope, &save_flow_ast, "save_it", (flow,)); match result { Ok(saved_flow) => { println!("Saved flow to database with ID: {}", saved_flow.get_id()); }, Err(err) => eprintln!("Error saving flow: {}", err), } // Save the signature requirement to the database using the Rhai function let save_req_script = "fn save_it(r) { return db::save_signature_requirement(r); }"; let save_req_ast = engine.compile(save_req_script).unwrap(); let result = engine.call_fn::(&mut scope, &save_req_ast, "save_it", (req,)); match result { Ok(saved_req) => { println!("Saved signature requirement to database with ID: {}", saved_req.get_id()); }, Err(err) => eprintln!("Error saving signature requirement: {}", err), } }, Err(err) => eprintln!("Error creating signature requirement: {}", err), } }, Err(err) => eprintln!("Error creating flow step: {}", err), } }, Err(err) => eprintln!("Error creating flow: {}", err), } Ok(()) }