use async_trait::async_trait;
use cano::prelude::*;
use rand::RngExt;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum Action {
Generate,
Count,
Complete,
}
struct GeneratorTask;
#[async_trait]
impl Task<Action> for GeneratorTask {
async fn run(&self, store: &MemoryStore) -> CanoResult<TaskResult<Action>> {
println!("🎲 GeneratorTask: Creating random numbers...");
let mut rng = rand::rng();
let numbers: Vec<u32> = (0..10).map(|_| rng.random_range(1..=100)).collect();
println!("Generated numbers: {:?}", numbers);
let even_numbers: Vec<u32> = numbers.into_iter().filter(|&n| n % 2 == 0).collect();
println!("Filtered to even numbers: {:?}", even_numbers);
store.put("even_numbers", even_numbers)?;
println!("✅ GeneratorTask: Stored even numbers, moving to Count\n");
Ok(TaskResult::Single(Action::Count))
}
}
struct CounterTask;
#[async_trait]
impl Task<Action> for CounterTask {
async fn run(&self, store: &MemoryStore) -> CanoResult<TaskResult<Action>> {
println!("🔢 CounterTask: Counting numbers...");
let numbers: Vec<u32> = store.get("even_numbers")?;
let count = numbers.len();
let sum: u32 = numbers.iter().sum();
println!("Found {} even numbers with sum: {}", count, sum);
store.put("count", count)?;
store.put("sum", sum)?;
println!("✅ CounterTask: Processing complete!\n");
Ok(TaskResult::Single(Action::Complete))
}
}
#[tokio::main]
async fn main() -> CanoResult<()> {
println!("🚀 Starting Task-based workflow example\n");
let store = MemoryStore::new();
let workflow = Workflow::new(store.clone())
.register(Action::Generate, GeneratorTask)
.register(Action::Count, CounterTask)
.add_exit_states(vec![Action::Complete]);
match workflow.orchestrate(Action::Generate).await {
Ok(_final_state) => {
println!("🎉 Workflow completed!");
println!("📊 Final Results:");
if let Ok(count) = store.get::<usize>("count") {
println!(" • Count of even numbers: {count}");
}
if let Ok(sum) = store.get::<u32>("sum") {
println!(" • Sum of even numbers: {sum}");
}
if let Ok(numbers) = store.get::<Vec<u32>>("even_numbers") {
println!(" • Even numbers: {numbers:?}");
}
}
Err(e) => {
eprintln!("❌ Workflow failed: {e}");
return Err(e);
}
}
println!("\n💡 Compare this Task-based approach with examples/workflow_simple.rs");
println!(" to see the difference between Task and Node implementations!");
Ok(())
}