#process #bpmn #flow #engine

snurr

Read BPMN 2.0 files and run the process flow

10 releases (5 breaking)

Uses new Rust 2024

new 0.8.2 May 10, 2025
0.8.1 May 9, 2025
0.7.0 Nov 6, 2024
0.6.1 Oct 20, 2024
0.3.5 Sep 16, 2024

#155 in Operating systems

Download history 2/week @ 2025-03-02 5/week @ 2025-03-09 57/week @ 2025-04-27 110/week @ 2025-05-04

167 downloads per month

MIT license

81KB
2K SLoC

Snurr

Build Status

Snurr can run the process flow from a Business Process Model and Notation (BPMN) 2.0 file created by https://demo.bpmn.io/new.

  • Add your own behavior with Rust code from a small API. The wiring is already setup from the file.
  • Easy to update the BPMN diagram with new Task and Gateways without the need to refactor your old code.
  • The BPMN file is the actual design. Forget outdated documentation.
  • Scaffold the initial BPMN diagram so you don't have to do the boilerplate code.
  • Contains no database.
  • Single or multithreaded (opt in)

Read the Snurr documentation and explore the tests folder for more examples.

NOTE: To view or edit BPMN files in your project you can use the BPMN Editor plugin in VS Code.

Tasks

Example

BPMN diagram used in example.

BPMN example

Usage

[dependencies]
snurr = "0.8"
log = "0.4"
pretty_env_logger = "0.5"
use snurr::{Eventhandler, Process};

extern crate pretty_env_logger;

#[derive(Debug, Default)]
struct Counter {
    count: u32,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    pretty_env_logger::init();

    let bpmn = Process::new("example.bpmn")?;
    let mut handler: Eventhandler<Counter> = Eventhandler::default();

    handler.add_task("Count 1", |input| {
        input.lock().unwrap().count += 1;
        None
    });

    handler.add_gateway("equal to 3", |input| {
        let result = if input.lock().unwrap().count == 3 {
            "YES"
        } else {
            "NO"
        };
        result.into()
    });

    let pr = bpmn.run(&handler, Counter::default())?;
    println!("Result: {:?}", pr.result);
    Ok(())
}

Output

If RUST_LOG=info is set when running example

 INFO  snurr::process::engine > Start: Begin process
 INFO  snurr::process::engine > SequenceFlow: count
 INFO  snurr::process::engine > Task: Count 1
 INFO  snurr::process::engine > SequenceFlow: control
 INFO  snurr::process::engine > Exclusive: equal to 3
 INFO  snurr::process::engine > SequenceFlow: NO
 INFO  snurr::process::engine > Task: Count 1
 INFO  snurr::process::engine > SequenceFlow: control
 INFO  snurr::process::engine > Exclusive: equal to 3
 INFO  snurr::process::engine > SequenceFlow: NO
 INFO  snurr::process::engine > Task: Count 1
 INFO  snurr::process::engine > SequenceFlow: control
 INFO  snurr::process::engine > Exclusive: equal to 3
 INFO  snurr::process::engine > SequenceFlow: YES
 INFO  snurr::process::engine > End: End process
Result: Counter { count: 3 }

Prepared sample

Run or copy the simple.rs in the examples folder

RUST_LOG=info cargo run --example simple

Dependencies

~2.2–3MB
~55K SLoC