1pub mod mosaik_protocol;
2pub mod tcp;
3pub mod types;
4
5use crate::{
6 tcp::{build_connection, ConnectionDirection},
7 types::{Attr, CreateResult, InputData, Meta, OutputData, OutputRequest, SimId, Time},
8};
9
10use async_std::task;
11use async_trait::async_trait;
12#[cfg(test)]
13use mockall::automock;
14use serde_json::{Map, Value};
15
16type AResult<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
17
18pub fn run_simulation<T: MosaikApi>(addr: ConnectionDirection, simulator: T) -> AResult<()> {
20 task::block_on(build_connection(addr, simulator))
21}
22
23#[cfg_attr(test, automock)]
26pub trait MosaikApi: Send + 'static {
27 fn init(
30 &mut self,
31 sid: SimId,
32 time_resolution: f64,
33 sim_params: Map<String, Value>,
34 ) -> Result<&'static Meta, String>;
35
36 fn create(
39 &mut self,
40 num: usize,
41 model_name: String,
42 model_params: Map<Attr, Value>,
43 ) -> Result<Vec<CreateResult>, String>;
44
45 fn setup_done(&self) -> Result<(), String>;
48
49 fn step(
52 &mut self,
53 time: Time,
54 inputs: InputData,
55 max_advance: Time,
56 ) -> Result<Option<Time>, String>;
57
58 fn get_data(&self, outputs: OutputRequest) -> Result<OutputData, String>;
60
61 fn stop(&self);
64
65 fn extra_method(
69 &mut self,
70 method: &str,
71 args: &Vec<Value>,
72 kwargs: &Map<String, Value>,
73 ) -> Result<Value, String> {
74 Err(format!(
75 "Method '{method}' not found with args: {args:?} and kwargs: {kwargs:?}"
76 ))
77 }
78}
79
80#[allow(dead_code)]
82#[async_trait]
83trait AsyncApi {
84 async fn get_progress();
85 async fn get_related_entities();
86 async fn get_data();
87 async fn set_data();
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use crate::MockMosaikApi;
94 use mockall::predicate::*;
95 use serde_json::json;
96
97 #[test]
98 fn test_extra_method_with_logic() {
99 let mut mock = MockMosaikApi::new();
100 let args = vec![json!(1), json!("hello")];
101 let kwargs = Map::new();
102
103 let actual_method = |method: &str| match method {
105 "example_method" => Ok(Value::String("example result".to_string())),
106 _ => Err(format!("Method not found: {method}")),
107 };
108
109 mock.expect_extra_method()
111 .with(
112 mockall::predicate::eq("example_method"),
113 mockall::predicate::eq(args.clone()),
114 mockall::predicate::eq(kwargs.clone()),
115 )
116 .returning(move |method, _, _| actual_method(method));
117
118 mock.expect_extra_method()
119 .with(
120 mockall::predicate::eq("unknown_method"),
121 mockall::predicate::eq(args.clone()),
122 mockall::predicate::eq(kwargs.clone()),
123 )
124 .returning(move |method, _, _| actual_method(method));
125
126 let result = mock.extra_method("example_method", &args, &kwargs);
128 assert_eq!(result, Ok(Value::String("example result".to_string())));
129
130 let result = mock.extra_method("unknown_method", &args, &kwargs);
132 assert_eq!(result, Err("Method not found: unknown_method".to_string()));
133 }
134}