1use std::time::Duration;
10
11use serde::{Deserialize, Serialize};
12use slim::runtime::RuntimeConfiguration as CoreRuntimeConfiguration;
13use slim_tracing::TracingConfiguration as CoreTracingConfiguration;
14
15use crate::{ServiceConfig, service::DataplaneConfig};
16
17#[derive(uniffi::Record, Clone, Debug, Serialize, Deserialize)]
21pub struct RuntimeConfig {
22 pub n_cores: u64,
24
25 pub thread_name: String,
27
28 pub drain_timeout: Duration,
30}
31
32impl Default for RuntimeConfig {
33 fn default() -> Self {
34 let core = CoreRuntimeConfiguration::default();
35 RuntimeConfig {
36 n_cores: core.n_cores() as u64,
37 thread_name: core.thread_name().to_string(),
38 drain_timeout: core.drain_timeout(),
39 }
40 }
41}
42
43impl From<RuntimeConfig> for CoreRuntimeConfiguration {
44 fn from(config: RuntimeConfig) -> Self {
45 CoreRuntimeConfiguration {
46 n_cores: config.n_cores as usize,
47 thread_name: config.thread_name,
48 drain_timeout: config.drain_timeout.into(),
49 }
50 }
51}
52
53impl From<CoreRuntimeConfiguration> for RuntimeConfig {
54 fn from(config: CoreRuntimeConfiguration) -> Self {
55 RuntimeConfig {
56 n_cores: config.n_cores() as u64,
57 thread_name: config.thread_name().to_string(),
58 drain_timeout: config.drain_timeout(),
59 }
60 }
61}
62
63#[derive(uniffi::Record, Clone, Debug, Serialize, Deserialize)]
67pub struct TracingConfig {
68 pub log_level: String,
70
71 pub display_thread_names: bool,
73
74 pub display_thread_ids: bool,
76
77 pub filters: Vec<String>,
79}
80
81impl Default for TracingConfig {
82 fn default() -> Self {
83 let core = CoreTracingConfiguration::default();
84 TracingConfig {
85 log_level: core.log_level().to_string(),
86 display_thread_names: core.display_thread_names(),
87 display_thread_ids: core.display_thread_ids(),
88 filters: core.filter().to_vec(),
89 }
90 }
91}
92
93impl From<TracingConfig> for CoreTracingConfiguration {
94 fn from(config: TracingConfig) -> Self {
95 CoreTracingConfiguration::default()
96 .with_log_level(config.log_level)
97 .with_display_thread_names(config.display_thread_names)
98 .with_display_thread_ids(config.display_thread_ids)
99 .with_filter(config.filters)
100 }
101}
102
103impl From<CoreTracingConfiguration> for TracingConfig {
104 fn from(config: CoreTracingConfiguration) -> Self {
105 TracingConfig {
106 log_level: config.log_level().to_string(),
107 display_thread_names: config.display_thread_names(),
108 display_thread_ids: config.display_thread_ids(),
109 filters: config.filter().to_vec(),
110 }
111 }
112}
113
114#[uniffi::export]
118pub fn new_runtime_config() -> RuntimeConfig {
119 RuntimeConfig::default()
120}
121
122#[uniffi::export]
124pub fn new_runtime_config_with(
125 n_cores: u64,
126 thread_name: String,
127 drain_timeout: Duration,
128) -> RuntimeConfig {
129 RuntimeConfig {
130 n_cores,
131 thread_name,
132 drain_timeout,
133 }
134}
135
136#[uniffi::export]
138pub fn new_tracing_config() -> TracingConfig {
139 TracingConfig::default()
140}
141
142#[uniffi::export]
144pub fn new_tracing_config_with(
145 log_level: String,
146 display_thread_names: bool,
147 display_thread_ids: bool,
148 filters: Vec<String>,
149) -> TracingConfig {
150 TracingConfig {
151 log_level,
152 display_thread_names,
153 display_thread_ids,
154 filters,
155 }
156}
157
158#[uniffi::export]
160pub fn new_service_config() -> ServiceConfig {
161 ServiceConfig::default()
162}
163
164#[uniffi::export]
166pub fn new_service_config_with(
167 node_id: Option<String>,
168 group_name: Option<String>,
169 dataplane: DataplaneConfig,
170) -> ServiceConfig {
171 ServiceConfig {
172 node_id,
173 group_name,
174 dataplane,
175 }
176}
177
178#[cfg(test)]
179mod tests {
180 use slim_service::ServiceConfiguration as CoreServiceConfiguration;
181
182 use super::*;
183
184 #[test]
185 fn test_runtime_configuration_default() {
186 let config = RuntimeConfig::default();
187 assert_eq!(config.n_cores, 0); assert_eq!(config.thread_name, "slim");
189 assert_eq!(config.drain_timeout, Duration::from_secs(10));
190 }
191
192 #[test]
193 fn test_runtime_configuration_roundtrip() {
194 let config = RuntimeConfig {
195 n_cores: 4,
196 thread_name: "test-runtime".to_string(),
197 drain_timeout: Duration::from_secs(30),
198 };
199
200 let core: CoreRuntimeConfiguration = config.clone().into();
201 let back: RuntimeConfig = core.into();
202
203 assert_eq!(back.n_cores, config.n_cores);
204 assert_eq!(back.thread_name, config.thread_name);
205 assert_eq!(back.drain_timeout, config.drain_timeout);
206 }
207
208 #[test]
209 fn test_tracing_configuration_default() {
210 let config = TracingConfig::default();
211 assert_eq!(config.log_level, "info");
212 let _ = config.display_thread_names;
215 let _ = config.display_thread_ids;
216 let _ = &config.filters;
217 }
218
219 #[test]
220 fn test_tracing_configuration_roundtrip() {
221 let config = TracingConfig {
222 log_level: "debug".to_string(),
223 display_thread_names: true,
224 display_thread_ids: true,
225 filters: vec!["slim=debug".to_string(), "tokio=info".to_string()],
226 };
227
228 let core: CoreTracingConfiguration = config.clone().into();
229 let back: TracingConfig = core.into();
230
231 assert_eq!(back.log_level, config.log_level);
232 assert_eq!(back.display_thread_names, config.display_thread_names);
233 assert_eq!(back.display_thread_ids, config.display_thread_ids);
234 assert_eq!(back.filters, config.filters);
235 }
236
237 #[test]
238 fn test_service_configuration_default() {
239 let config = ServiceConfig::default();
240 assert!(config.node_id.is_none());
241 assert!(config.group_name.is_none());
242 }
243
244 #[test]
245 fn test_service_configuration_roundtrip() {
246 let config = ServiceConfig {
247 node_id: Some("test-node".to_string()),
248 group_name: Some("test-group".to_string()),
249 dataplane: DataplaneConfig::default(),
250 };
251
252 let core: CoreServiceConfiguration = config.clone().into();
253 let back: ServiceConfig = core.into();
254
255 assert_eq!(back.node_id, config.node_id);
256 assert_eq!(back.group_name, config.group_name);
257 }
258
259 #[test]
260 fn test_constructor_functions() {
261 let runtime = new_runtime_config();
262 assert_eq!(runtime.n_cores, 0);
263
264 let runtime_custom =
265 new_runtime_config_with(4, "custom".to_string(), Duration::from_secs(20));
266 assert_eq!(runtime_custom.n_cores, 4);
267 assert_eq!(runtime_custom.thread_name, "custom");
268 assert_eq!(runtime_custom.drain_timeout, Duration::from_secs(20));
269
270 let tracing = new_tracing_config();
271 assert_eq!(tracing.log_level, "info");
272
273 let tracing_custom = new_tracing_config_with(
274 "debug".to_string(),
275 true,
276 true,
277 vec!["slim=debug".to_string()],
278 );
279 assert_eq!(tracing_custom.log_level, "debug");
280 assert!(tracing_custom.display_thread_names);
281
282 let service = new_service_config();
283 assert!(service.node_id.is_none());
284
285 let service_custom = new_service_config_with(
286 Some("node-1".to_string()),
287 Some("group-1".to_string()),
288 DataplaneConfig::default(),
289 );
290 assert_eq!(service_custom.node_id, Some("node-1".to_string()));
291 assert_eq!(service_custom.group_name, Some("group-1".to_string()));
292 }
293}