pub struct StateMachineBuilderFactory;Expand description
Factory for creating state machine builders
Implementations§
Source§impl StateMachineBuilderFactory
impl StateMachineBuilderFactory
Sourcepub fn create<S, E, C>() -> StateMachineBuilder<S, E, C>
pub fn create<S, E, C>() -> StateMachineBuilder<S, E, C>
Examples found in repository?
examples/traffic_light_example.rs (lines 47-48)
44pub fn build_traffic_light_system(
45) -> StateMachine<TrafficLightState, TrafficLightEvent, TrafficContext> {
46 let mut builder =
47 StateMachineBuilderFactory::create::<TrafficLightState, TrafficLightEvent, TrafficContext>(
48 );
49
50 // Configure the state machine based on available features
51 configure_basic_transitions(&mut builder);
52
53 #[cfg(feature = "extended")]
54 configure_entry_exit_actions(&mut builder);
55
56 #[cfg(feature = "guards")]
57 configure_priority_transitions(&mut builder);
58
59 #[cfg(feature = "timeout")]
60 configure_timeouts(&mut builder);
61
62 builder.set_fail_callback(Arc::new(|state, event, ctx| {
63 eprintln!(
64 "WARNING: Invalid transition from {:?} with {:?} at intersection {}",
65 state, event, ctx.intersection_id
66 );
67 }));
68 builder.id("TrafficLightController").build()
69}More examples
examples/order_example.rs (line 46)
43fn basic_example() {
44 println!("=== Basic State Machine Example ===");
45
46 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
47
48 builder
49 .external_transition()
50 .from(OrderState::New)
51 .to(OrderState::PaymentPending)
52 .on(OrderEvent::Pay)
53 .perform(|_s, _e, ctx| {
54 println!("Order {} payment initiated", ctx.order_id);
55 });
56
57 builder
58 .external_transition()
59 .from(OrderState::PaymentPending)
60 .to(OrderState::PaymentReceived)
61 .on(OrderEvent::ConfirmPayment)
62 .perform(|_s, _e, ctx| {
63 println!("Payment confirmed for order {}", ctx.order_id);
64 });
65
66 let state_machine = builder.id("BasicOrderMachine").build();
67
68 let context = OrderContext {
69 order_id: "ORD-001".to_string(),
70 amount: 99.99,
71 customer_id: "CUST-123".to_string(),
72 };
73
74 let result = state_machine.fire_event(OrderState::New, OrderEvent::Pay, context.clone());
75 println!("Transition result: {:?}", result);
76}
77
78/// Example 2: With history tracking (requires 'history' feature)
79#[cfg(feature = "history")]
80fn history_example() {
81 println!("\n=== History Tracking Example ===");
82
83 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
84
85 builder
86 .external_transition()
87 .from(OrderState::New)
88 .to(OrderState::PaymentPending)
89 .on(OrderEvent::Pay)
90 .perform(|_s, _e, _c| {});
91
92 builder
93 .external_transition()
94 .from(OrderState::PaymentPending)
95 .to(OrderState::PaymentReceived)
96 .on(OrderEvent::ConfirmPayment)
97 .perform(|_s, _e, _c| {});
98
99 builder
100 .external_transition()
101 .from(OrderState::PaymentReceived)
102 .to(OrderState::Processing)
103 .on(OrderEvent::Process)
104 .perform(|_s, _e, _c| {});
105
106 let state_machine = builder.id("HistoryOrderMachine").build();
107
108 let context = OrderContext {
109 order_id: "ORD-002".to_string(),
110 amount: 149.99,
111 customer_id: "CUST-456".to_string(),
112 };
113
114 // Execute multiple transitions
115 let _ = state_machine.fire_event(OrderState::New, OrderEvent::Pay, context.clone());
116 let _ = state_machine.fire_event(
117 OrderState::PaymentPending,
118 OrderEvent::ConfirmPayment,
119 context.clone(),
120 );
121 let _ = state_machine.fire_event(OrderState::PaymentReceived, OrderEvent::Process, context);
122
123 // Check history
124 let history = state_machine.get_history();
125 println!("Transition history:");
126 for (i, record) in history.iter().enumerate() {
127 println!(
128 " {}. {:?} -> {:?} via {:?} (success: {})",
129 i + 1,
130 record.from,
131 record.to,
132 record.event,
133 record.success
134 );
135 }
136}
137
138/// Example 3: With entry/exit actions (requires 'extended' feature)
139#[cfg(feature = "extended")]
140fn extended_example() {
141 println!("\n=== Extended State Machine Example ===");
142
143 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
144
145 builder
146 .with_entry_action(OrderState::Processing, |state, ctx| {
147 println!(
148 "ENTRY: Starting to process order {} in state {:?}",
149 ctx.order_id, state
150 );
151 })
152 .with_exit_action(OrderState::Processing, |state, ctx| {
153 println!(
154 "EXIT: Finished processing order {} from state {:?}",
155 ctx.order_id, state
156 );
157 })
158 .with_entry_action(OrderState::Shipped, |_state, ctx| {
159 println!("ENTRY: Order {} has been shipped!", ctx.order_id);
160 });
161
162 builder
163 .external_transition()
164 .from(OrderState::PaymentReceived)
165 .to(OrderState::Processing)
166 .on(OrderEvent::Process)
167 .perform(|_s, _e, _c| {});
168
169 builder
170 .external_transition()
171 .from(OrderState::Processing)
172 .to(OrderState::Shipped)
173 .on(OrderEvent::Ship)
174 .perform(|_s, _e, _c| {});
175
176 let state_machine = builder.id("ExtendedOrderMachine").build();
177
178 let context = OrderContext {
179 order_id: "ORD-003".to_string(),
180 amount: 299.99,
181 customer_id: "CUST-789".to_string(),
182 };
183
184 let _ = state_machine.fire_event(
185 OrderState::PaymentReceived,
186 OrderEvent::Process,
187 context.clone(),
188 );
189 let _ = state_machine.fire_event(OrderState::Processing, OrderEvent::Ship, context);
190}
191
192/// Example 4: With metrics (requires 'metrics' feature)
193#[cfg(feature = "metrics")]
194fn metrics_example() {
195 println!("\n=== Metrics Collection Example ===");
196
197 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
198
199 // Add multiple transitions
200 builder
201 .external_transition()
202 .from(OrderState::New)
203 .to(OrderState::PaymentPending)
204 .on(OrderEvent::Pay)
205 .perform(|_s, _e, _c| {});
206
207 builder
208 .external_transition()
209 .from(OrderState::PaymentPending)
210 .to(OrderState::PaymentReceived)
211 .on(OrderEvent::ConfirmPayment)
212 .when(|_s, _e, ctx| ctx.amount > 0.0)
213 .perform(|_s, _e, _c| {});
214
215 builder
216 .external_transitions()
217 .from_among(vec![
218 OrderState::New,
219 OrderState::PaymentPending,
220 OrderState::Processing,
221 ])
222 .to(OrderState::Cancelled)
223 .on(OrderEvent::Cancel)
224 .perform(|_s, _e, _c| {});
225
226 let state_machine = builder.id("MetricsOrderMachine").build();
227
228 // Simulate multiple orders
229 for i in 0..10 {
230 let context = OrderContext {
231 order_id: format!("ORD-{:03}", i),
232 amount: (i as f64) * 10.0,
233 customer_id: format!("CUST-{:03}", i),
234 };
235
236 let _ = state_machine.fire_event(OrderState::New, OrderEvent::Pay, context.clone());
237
238 if i % 3 == 0 {
239 // Some orders get cancelled
240 let _ =
241 state_machine.fire_event(OrderState::PaymentPending, OrderEvent::Cancel, context);
242 } else {
243 // Others proceed normally
244 let _ = state_machine.fire_event(
245 OrderState::PaymentPending,
246 OrderEvent::ConfirmPayment,
247 context,
248 );
249 }
250 }
251
252 // Get and display metrics
253 let metrics = state_machine.get_metrics();
254 println!("State Machine Metrics:");
255 println!(" Total transitions: {}", metrics.total_transitions);
256 println!(" Successful: {}", metrics.successful_transitions);
257 println!(" Failed: {}", metrics.failed_transitions);
258 println!(" Success rate: {:.2}%", metrics.success_rate() * 100.0);
259
260 if let Some(avg_time) = metrics.average_transition_time() {
261 println!(" Average transition time: {:?}", avg_time);
262 }
263
264 println!(" State visit counts:");
265 for (state, count) in &metrics.state_visit_counts {
266 println!(" {}: {}", state, count);
267 }
268}
269
270/// Example 5: With guard priorities (requires 'guards' feature)
271#[cfg(feature = "guards")]
272fn guards_example() {
273 println!("\n=== Guard Priorities Example ===");
274
275 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
276
277 // Multiple transitions with different priorities
278 builder
279 .external_transition()
280 .from(OrderState::PaymentReceived)
281 .to(OrderState::Processing)
282 .on(OrderEvent::Process)
283 .when(|_s, _e, ctx| ctx.amount < 100.0)
284 .with_priority(10)
285 .perform(|_s, _e, ctx| {
286 println!(
287 "Processing small order {} (amount: {})",
288 ctx.order_id, ctx.amount
289 );
290 });
291
292 builder
293 .external_transition()
294 .from(OrderState::PaymentReceived)
295 .to(OrderState::Processing)
296 .on(OrderEvent::Process)
297 .when(|_s, _e, ctx| ctx.amount >= 100.0 && ctx.amount < 1000.0)
298 .with_priority(20)
299 .perform(|_s, _e, ctx| {
300 println!(
301 "Processing medium order {} (amount: {})",
302 ctx.order_id, ctx.amount
303 );
304 });
305
306 builder
307 .external_transition()
308 .from(OrderState::PaymentReceived)
309 .to(OrderState::Processing)
310 .on(OrderEvent::Process)
311 .when(|_s, _e, ctx| ctx.amount >= 1000.0)
312 .with_priority(30)
313 .perform(|_s, _e, ctx| {
314 println!(
315 "Processing large order {} (amount: {}) - Priority handling!",
316 ctx.order_id, ctx.amount
317 );
318 });
319
320 let state_machine = builder.id("GuardsOrderMachine").build();
321
322 // Test with different order amounts
323 let contexts = vec![
324 OrderContext {
325 order_id: "ORD-SMALL".to_string(),
326 amount: 50.0,
327 customer_id: "C1".to_string(),
328 },
329 OrderContext {
330 order_id: "ORD-MEDIUM".to_string(),
331 amount: 500.0,
332 customer_id: "C2".to_string(),
333 },
334 OrderContext {
335 order_id: "ORD-LARGE".to_string(),
336 amount: 5000.0,
337 customer_id: "C3".to_string(),
338 },
339 ];
340
341 for context in contexts {
342 let _ = state_machine.fire_event(OrderState::PaymentReceived, OrderEvent::Process, context);
343 }
344}
345
346/// Example 6: With visualization (requires 'visualization' feature)
347#[cfg(feature = "visualization")]
348fn visualization_example() {
349 println!("\n=== Visualization Example ===");
350
351 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
352
353 // Build a complete order flow
354 builder
355 .external_transition()
356 .from(OrderState::New)
357 .to(OrderState::PaymentPending)
358 .on(OrderEvent::Pay)
359 .perform(|_s, _e, _c| {});
360
361 builder
362 .external_transition()
363 .from(OrderState::PaymentPending)
364 .to(OrderState::PaymentReceived)
365 .on(OrderEvent::ConfirmPayment)
366 .perform(|_s, _e, _c| {});
367
368 builder
369 .external_transition()
370 .from(OrderState::PaymentReceived)
371 .to(OrderState::Processing)
372 .on(OrderEvent::Process)
373 .perform(|_s, _e, _c| {});
374
375 builder
376 .external_transition()
377 .from(OrderState::Processing)
378 .to(OrderState::Shipped)
379 .on(OrderEvent::Ship)
380 .perform(|_s, _e, _c| {});
381
382 builder
383 .external_transition()
384 .from(OrderState::Shipped)
385 .to(OrderState::Delivered)
386 .on(OrderEvent::Deliver)
387 .perform(|_s, _e, _c| {});
388
389 builder
390 .external_transitions()
391 .from_among(vec![
392 OrderState::New,
393 OrderState::PaymentPending,
394 OrderState::Processing,
395 ])
396 .to(OrderState::Cancelled)
397 .on(OrderEvent::Cancel)
398 .perform(|_s, _e, _c| {});
399
400 builder
401 .external_transition()
402 .from(OrderState::Cancelled)
403 .to(OrderState::Refunded)
404 .on(OrderEvent::Refund)
405 .perform(|_s, _e, _c| {});
406
407 let state_machine = builder.id("VisualOrderMachine").build();
408
409 println!("DOT Format:");
410 println!("{}", state_machine.to_dot());
411
412 println!("\nPlantUML Format:");
413 println!("{}", state_machine.to_plantuml());
414}
415
416/// Example 7: With parallel regions (requires 'parallel' feature)
417#[cfg(feature = "parallel")]
418fn parallel_example() {
419 println!("\n=== Parallel Regions Example ===");
420
421 // Order processing region
422 let mut order_builder =
423 StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
424 order_builder
425 .external_transition()
426 .from(OrderState::New)
427 .to(OrderState::Processing)
428 .on(OrderEvent::Process)
429 .perform(|_s, _e, ctx| {
430 println!("Order region: Processing order {}", ctx.order_id);
431 });
432
433 // Payment processing region (using same states/events for simplicity)
434 let mut payment_builder =
435 StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
436 payment_builder
437 .external_transition()
438 .from(OrderState::PaymentPending)
439 .to(OrderState::PaymentReceived)
440 .on(OrderEvent::ConfirmPayment)
441 .perform(|_s, _e, ctx| {
442 println!(
443 "Payment region: Payment confirmed for order {}",
444 ctx.order_id
445 );
446 });
447
448 let mut parallel_machine = ParallelStateMachine::new();
449 parallel_machine.add_region(order_builder.id("OrderRegion").build());
450 parallel_machine.add_region(payment_builder.id("PaymentRegion").build());
451
452 let context = OrderContext {
453 order_id: "ORD-PARALLEL".to_string(),
454 amount: 199.99,
455 customer_id: "CUST-P1".to_string(),
456 };
457
458 // Fire events in parallel regions
459 println!("Firing Process event in parallel regions:");
460 let results = parallel_machine.fire_event(
461 vec![OrderState::New, OrderState::PaymentPending],
462 OrderEvent::Process,
463 context.clone(),
464 );
465
466 for (i, result) in results.iter().enumerate() {
467 println!(" Region {}: {:?}", i, result);
468 }
469
470 println!("Firing ConfirmPayment event in parallel regions:");
471 let results = parallel_machine.fire_event(
472 vec![OrderState::Processing, OrderState::PaymentPending],
473 OrderEvent::ConfirmPayment,
474 context,
475 );
476
477 for (i, result) in results.iter().enumerate() {
478 println!(" Region {}: {:?}", i, result);
479 }
480}
481
482/// Example 8: Complete example with multiple features
483#[cfg(all(feature = "history", feature = "metrics", feature = "extended"))]
484fn complete_example() {
485 println!("\n=== Complete Example with Multiple Features ===");
486
487 let mut builder = StateMachineBuilderFactory::create::<OrderState, OrderEvent, OrderContext>();
488
489 // Configure entry/exit actions
490 builder
491 .with_entry_action(OrderState::Processing, |_s, ctx| {
492 println!("[ENTRY] Starting to process order {}", ctx.order_id);
493 })
494 .with_exit_action(OrderState::Processing, |_s, ctx| {
495 println!("[EXIT] Finished processing order {}", ctx.order_id);
496 });
497
498 // Build transitions
499 builder
500 .external_transition()
501 .from(OrderState::New)
502 .to(OrderState::PaymentPending)
503 .on(OrderEvent::Pay)
504 .perform(|_s, _e, ctx| {
505 println!("Payment initiated for ${}", ctx.amount);
506 });
507
508 builder
509 .external_transition()
510 .from(OrderState::PaymentPending)
511 .to(OrderState::PaymentReceived)
512 .on(OrderEvent::ConfirmPayment)
513 .when(|_s, _e, ctx| ctx.amount > 0.0)
514 .perform(|_s, _e, ctx| {
515 println!("Payment confirmed: ${}", ctx.amount);
516 });
517
518 builder
519 .external_transition()
520 .from(OrderState::PaymentReceived)
521 .to(OrderState::Processing)
522 .on(OrderEvent::Process)
523 .perform(|_s, _e, _c| {});
524
525 builder
526 .external_transition()
527 .from(OrderState::Processing)
528 .to(OrderState::Shipped)
529 .on(OrderEvent::Ship)
530 .perform(|_s, _e, ctx| {
531 println!("Order {} shipped", ctx.order_id);
532 });
533
534 builder.set_fail_callback(Arc::new(|state, event, ctx| {
535 println!(
536 "FAILED: Cannot handle {:?} in state {:?} for order {}",
537 event, state, ctx.order_id
538 );
539 }));
540
541 let state_machine = builder.id("CompleteOrderMachine").build();
542
543 // Process an order through the complete flow
544 let context = OrderContext {
545 order_id: "ORD-COMPLETE".to_string(),
546 amount: 999.99,
547 customer_id: "CUST-VIP".to_string(),
548 };
549
550 println!("\nProcessing order through complete flow:");
551 let states = [
552 (OrderState::New, OrderEvent::Pay),
553 (OrderState::PaymentPending, OrderEvent::ConfirmPayment),
554 (OrderState::PaymentReceived, OrderEvent::Process),
555 (OrderState::Processing, OrderEvent::Ship),
556 ];
557
558 for (state, event) in &states {
559 let result = state_machine.fire_event(state.clone(), event.clone(), context.clone());
560 println!(" {:?} + {:?} = {:?}", state, event, result);
561 }
562
563 // Try an invalid transition
564 println!("\nTrying invalid transition:");
565 let _ = state_machine.fire_event(OrderState::Shipped, OrderEvent::Pay, context);
566
567 // Display collected data
568 println!("\nHistory:");
569 for record in state_machine.get_history() {
570 println!(
571 " {:?} -> {:?} (success: {})",
572 record.from, record.to, record.success
573 );
574 }
575
576 println!("\nMetrics:");
577 let metrics = state_machine.get_metrics();
578 println!(
579 " Total: {}, Success: {}, Failed: {}",
580 metrics.total_transitions, metrics.successful_transitions, metrics.failed_transitions
581 );
582}Auto Trait Implementations§
impl Freeze for StateMachineBuilderFactory
impl RefUnwindSafe for StateMachineBuilderFactory
impl Send for StateMachineBuilderFactory
impl Sync for StateMachineBuilderFactory
impl Unpin for StateMachineBuilderFactory
impl UnsafeUnpin for StateMachineBuilderFactory
impl UnwindSafe for StateMachineBuilderFactory
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more