Generating Rust Code
Rust a is a relatively new programming language aiming to guarantee memory-safety and thread-safety. Rust is fast and memory-efficient with no runtime or garbage collector. More information about Rust is available at https://www.rust-lang.org
To generate Rust code call the code generator with the following commandline flag −l Rust
.
The generated code is using basic Rust features like match
, if/then/else
and can easily be understood.
The output name -o test
defines the generated state machine file name (Note the lower case ’t’ to follow Rust convention), the name of the state machine type and the prefix for the event and state enums.
The following image shows a simple microwave oven in the integrated state machine editor.
Code generation works as follows:
java -cp "path to installation/bin/*" codegen.Main -l rust -p ssc -o oven oven.xml
The generator uses the macro features of Rust. A concrete type of a machine must be defined
by using a def_fsm
call before the machine can be used.
// define state machine def_fsm!(&mut UserData, &mut crate::Timers<OvenEvents>, timer_id:usize=99,time:u32=0); let mut timers = Timers::new(); let mut myfsm : Oven = Default::default(); let mut msg = OvenEvents::EvInc; myfsm.handle_event(msg, &mut data, &mut timers); ...
The first macro parameter is a user defined type used as a parameter of
the state machine handler. It is available inside the event handler with
variable name data
and type UserData
.
The intended purpose is to provide a way for the user to hand over any kind of data to the state machine handler function which can then be used in the state machine. A simple use case is to hand over variables that acts as guards in state transitions.
The other intended purpose is that the UserData
type must provide a logger function of a predefined
signature in case the state machine was generated with the trace command line parameter
-Trace
. This allows to trace the state transitions and event flow.
The second macro parameter allows to hand over another user defined type intended to realize a timer service. Whether the state machine needs and uses a timer service and how it is implemented is totally in the user's hand. A microwave oven example is provided in the samples folder. It implemets a basic timer service for realizing the timeout for the cooking time.
Note: presently there is no possibliy to avoid the handover of the UserData
and
Timer
struct. This might change in later versions.
All further parameters are optional and simply added to the state machine struct.
In the code above an example with parameters x
and y
is shown.
The complete example is available here. Built it with cargo build
and then run it with cargo run
. In the src folder you will find command line examples how to model the state machine and build the Rust code. If you run the code type in events and send them to the state machine handler by pressing return.
You should see this output on the command line:
cargo run ... Oven demo program written in Rust Type in one or more commands and then press return to send them to the state machine Supported commands: o to open the door c to close the door + to increase the cooking time - to decrease the door P set oven power to high p set oven power to low
How to go on from here:
- Download the codegen which includes all the examples
- Modify the state machine model file and re-generate the Rust code again and explore your changes.
- Read the manual about all the functions the code generator provides
Please note that the Rust back-end is work-in-progress. Your feedback is highly welcome!