sync_decision/
sync_decision.rs1use std::sync::Mutex;
5
6use rutis::{CordisError, Ctx, Event, EventKey, SyncEvent, SyncNext};
7
8struct BeforeSave {
9 candidate: u64,
10}
11impl Event for BeforeSave {
12 const NAME: &'static str = "example::BeforeSave";
13 type Value = u64;
14}
15impl SyncEvent for BeforeSave {}
16const BEFORE_SAVE: EventKey<BeforeSave> = EventKey::named("before-save");
17
18fn save(ctx: &Ctx, state: &Mutex<u64>, candidate: u64) -> Result<u64, CordisError> {
19 let mut current = state.lock().unwrap();
20 let proposed =
21 ctx.events()
22 .waterfall_sync(ctx, &BEFORE_SAVE, &BeforeSave { candidate }, |_, event| {
23 Ok((*current).max(event.candidate))
24 })?;
25 if proposed < *current {
27 return Err(CordisError::Validation {
28 issues: vec!["saved value must not decrease".into()],
29 });
30 }
31 *current = proposed;
32 Ok(proposed)
33}
34
35#[tokio::main]
36async fn main() -> Result<(), Box<dyn std::error::Error>> {
37 let root = Ctx::root()?;
38 root.events().on_waterfall_sync(
39 &root,
40 &BEFORE_SAVE,
41 |_: &Ctx, _: &BeforeSave, next: SyncNext<'_, BeforeSave>| {
42 Ok(next.call()?.min(100))
44 },
45 )?;
46 let state = Mutex::new(10);
47 assert_eq!(save(&root, &state, 120)?, 100);
48 println!("saved {}", state.lock().unwrap());
49 root.shutdown().await?;
50 Ok(())
51}