use std::marker::PhantomData;
use thread_aware::ThreadAware;
use thread_aware::affinity::Affinity;
use crate::Clock;
use crate::runtime::clock_driver::ClockDriver;
use crate::state::ClockState;
#[derive(Debug, Default, Clone, Copy)]
#[non_exhaustive]
pub struct Isolated;
#[derive(Debug)]
#[non_exhaustive]
pub struct Shared;
#[derive(Debug)]
pub struct InactiveClock<S = Isolated> {
state: ClockState,
_marker: PhantomData<fn() -> S>,
}
impl Clone for InactiveClock<Isolated> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
_marker: PhantomData,
}
}
}
impl Default for InactiveClock<Isolated> {
fn default() -> Self {
Self {
state: ClockState::new_system(),
_marker: PhantomData,
}
}
}
impl ThreadAware for InactiveClock<Isolated> {
fn relocate(&mut self, source: Option<Affinity>, destination: Affinity) {
self.state.relocate(source, destination);
}
}
#[cfg(any(feature = "rt-shared", test))]
impl InactiveClock<Shared> {
#[must_use]
pub fn new_shared() -> Self {
Self {
state: ClockState::new_system_shared(),
_marker: PhantomData,
}
}
}
impl<S> InactiveClock<S> {
#[must_use]
pub fn activate(self) -> (Clock, ClockDriver) {
let state = self.state;
let clock = Clock::new(state.clone());
let driver = ClockDriver::new(state);
(clock, driver)
}
}
#[cfg(any(feature = "test-util", test))]
impl From<crate::ClockControl> for InactiveClock<Isolated> {
fn from(control: crate::ClockControl) -> Self {
Self {
state: ClockState::ClockControl(control),
_marker: PhantomData,
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use static_assertions::{assert_impl_all, assert_not_impl_any};
use super::*;
use crate::ClockControl;
#[test]
fn assert_types() {
assert_impl_all!(InactiveClock: Send, Sync, Clone);
assert_impl_all!(InactiveClock<Shared>: Send, Sync);
assert_not_impl_any!(InactiveClock<Shared>: Clone);
}
#[test]
fn activate_ok() {
let inactive_clock = InactiveClock::default();
let (clock, driver) = inactive_clock.activate();
assert!(matches!(clock.clock_state(), ClockState::System(_)));
assert!(matches!(&driver.state, &ClockState::System(_)));
}
#[test]
fn activate_shared_ok() {
let inactive_clock = InactiveClock::new_shared();
let (clock, driver) = inactive_clock.activate();
assert!(matches!(clock.clock_state(), ClockState::System(_)));
assert!(matches!(&driver.state, &ClockState::System(_)));
}
#[test]
fn activate_with_fake_clock_ok() {
let inactive_clock = InactiveClock::from(ClockControl::new());
let (clock, driver) = inactive_clock.activate();
assert!(matches!(clock.clock_state(), ClockState::ClockControl(_)));
assert!(matches!(&driver.state, &ClockState::ClockControl(_)));
}
}