use cano::prelude::*;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum Step {
Classify,
FastPath,
SlowPath,
Done,
}
struct Config {
use_fast_path: bool,
}
#[resource]
impl Resource for Config {}
struct Classifier;
#[task::router(state = Step)]
impl Classifier {
async fn route(&self, res: &Resources) -> Result<TaskResult<Step>, CanoError> {
let config = res.get::<Config, _>("config")?;
if config.use_fast_path {
println!("classifier : fast path selected");
Ok(TaskResult::Single(Step::FastPath))
} else {
println!("classifier : slow path selected");
Ok(TaskResult::Single(Step::SlowPath))
}
}
}
struct FastProcessor;
#[task(state = Step)]
impl FastProcessor {
async fn run_bare(&self) -> Result<TaskResult<Step>, CanoError> {
println!("fast path : processing quickly...");
Ok(TaskResult::Single(Step::Done))
}
}
struct SlowProcessor;
#[task(state = Step)]
impl SlowProcessor {
async fn run_bare(&self) -> Result<TaskResult<Step>, CanoError> {
println!("slow path : processing thoroughly...");
Ok(TaskResult::Single(Step::Done))
}
}
fn build_workflow(use_fast_path: bool) -> Workflow<Step> {
let config = Config { use_fast_path };
let resources = Resources::new().insert("config", config);
Workflow::new(resources)
.register_router(Step::Classify, Classifier)
.register(Step::FastPath, FastProcessor)
.register(Step::SlowPath, SlowProcessor)
.add_exit_state(Step::Done)
}
#[tokio::main]
async fn main() -> CanoResult<()> {
println!("=== fast-path run ===");
let workflow = build_workflow(true);
let result = workflow.orchestrate(Step::Classify).await?;
assert_eq!(result, Step::Done);
println!("completed at {result:?}\n");
println!("=== slow-path run ===");
let workflow = build_workflow(false);
let result = workflow.orchestrate(Step::Classify).await?;
assert_eq!(result, Step::Done);
println!("completed at {result:?}");
Ok(())
}