use std::sync::{Arc, OnceLock};
use crate::exception::ExceptionManager;
use crate::port::PortDriverBase;
use crate::trace::TraceManager;
#[derive(Clone)]
pub struct PortServices {
trace: Arc<TraceManager>,
exceptions: Arc<ExceptionManager>,
}
impl PortServices {
pub fn new(trace: Arc<TraceManager>) -> Self {
let exceptions = Arc::new(ExceptionManager::new());
trace.set_exception_sink(exceptions.clone());
Self { trace, exceptions }
}
pub fn global() -> Self {
static GLOBAL: OnceLock<PortServices> = OnceLock::new();
GLOBAL
.get_or_init(|| PortServices::new(Arc::new(TraceManager::new())))
.clone()
}
pub fn trace(&self) -> &Arc<TraceManager> {
&self.trace
}
pub fn exceptions(&self) -> &Arc<ExceptionManager> {
&self.exceptions
}
pub(crate) fn bind(&self, base: &mut PortDriverBase) {
base.trace = Some(self.trace.clone());
base.bind_exception_sink(self.exceptions.clone());
}
}
impl Default for PortServices {
fn default() -> Self {
Self::global()
}
}
impl std::fmt::Debug for PortServices {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PortServices").finish_non_exhaustive()
}
}