use crate::error::{Error, Result};
use crate::transport::factory::{create_transports, TransportOptions};
use crate::transport::Router;
use std::sync::{Arc, Mutex, OnceLock};
static GLOBAL_TRANSPORT: OnceLock<Arc<Mutex<Router>>> = OnceLock::new();
pub fn get_singleton_transport(options: Option<&TransportOptions>) -> Result<Arc<Mutex<Router>>> {
if let Some(transport) = GLOBAL_TRANSPORT.get() {
return Ok(Arc::clone(transport));
}
let default_options = TransportOptions::new();
let opts = options.unwrap_or(&default_options);
let router = create_default_transport(opts)?;
let transport = Arc::new(Mutex::new(router));
match GLOBAL_TRANSPORT.set(Arc::clone(&transport)) {
Ok(()) => Ok(transport),
Err(_) => {
Ok(Arc::clone(GLOBAL_TRANSPORT.get().unwrap()))
}
}
}
pub fn create_default_transport(options: &TransportOptions) -> Result<Router> {
let all_devices = create_transports(options)?;
if all_devices.is_empty() {
return Err(Error::DeviceNotFound("No CAN-FD devices found".to_string()));
}
let mut router = Router::new(all_devices);
router.set_timeout(options.timeout);
Ok(router)
}
#[cfg(test)]
pub fn reset_singleton() {
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_transport_options_default() {
let opts = TransportOptions::new();
assert_eq!(opts.timeout, std::time::Duration::from_millis(100));
assert!(!opts.disable_brs);
assert!(opts.fdcanusb_paths.is_empty());
assert!(opts.socketcan_interfaces.is_empty());
}
#[test]
fn test_create_default_transport_no_devices() {
let opts = TransportOptions::new();
let result = create_default_transport(&opts);
let _ = result;
}
#[test]
fn test_get_singleton_returns_same_instance() {
let _ = get_singleton_transport(None);
}
}