1#![doc(test(attr(deny(unused_must_use))))]
8#![doc = std::include_str!(concat!(env!("OUT_DIR"), "/crate-docs.md"))]
9
10pub mod engine;
11pub mod events;
12pub mod executor;
13#[cfg(feature = "global_allocator")]
14mod global_allocator;
15pub mod port;
16pub mod test_helpers;
17pub mod time;
18pub mod traits;
19pub mod types;
20
21#[macro_export]
23macro_rules! run_simulation {
24 ($engine:ident) => {
25 $engine.run().unwrap();
26 };
27 ($engine:ident, $expect:expr) => {
28 match $engine.run() {
29 Ok(()) => panic!("Expected an error!"),
30 Err(e) => assert_eq!(&format!("{e}"), $expect),
31 }
32 };
33}
34
35#[macro_export]
40macro_rules! spawn_subcomponent {
41 ($($spawner:ident).+ ; $($block:ident).+) => {
42 let sub_block = $($block).+.borrow_mut().take().unwrap();
43 $($spawner).+.spawn(async move { sub_block.run().await } );
44 };
45}
46
47#[cfg(test)]
48mod tests {
49 use std::cell::{Cell, RefCell};
50 use std::rc::Rc;
51
52 use async_trait::async_trait;
53 use gwr_track::tracker::dev_null_tracker;
54
55 use crate::engine::Engine;
56 use crate::traits::Runnable;
57 use crate::types::SimResult;
58
59 struct TestComponent {
60 ran: Rc<Cell<bool>>,
61 }
62
63 #[async_trait(?Send)]
64 impl Runnable for TestComponent {
65 async fn run(&self) -> SimResult {
66 self.ran.set(true);
67 Ok(())
68 }
69 }
70
71 #[test]
72 fn spawn_subcomponent_spawns_and_runs_component() {
73 let tracker = dev_null_tracker();
74 let mut engine = Engine::new(&tracker);
75 let spawner = engine.spawner();
76 let ran = Rc::new(Cell::new(false));
77 let component = RefCell::new(Some(TestComponent { ran: ran.clone() }));
78
79 spawn_subcomponent!(spawner; component);
80
81 engine.run().unwrap();
82
83 assert!(ran.get());
84 assert!(component.borrow().is_none());
85 }
86}