use std::future::Future;
use std::pin::Pin;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use crate::domain::subject::Subject;
pub const NOT_SUPPORTED: &str = "virtual clocks not supported by this substrate";
#[derive(Clone, Copy, Debug)]
pub struct ClockState {
pub virtualised: bool,
pub epoch_millis: i64,
pub offset_millis: i64,
pub rate: f64,
pub frozen: bool,
}
pub trait ClockControl: Send + Sync + 'static {
fn now<'a>(
&'a self,
subject: &'a Subject,
) -> Pin<Box<dyn Future<Output = Result<i64, String>> + Send + 'a>> {
Box::pin(async move {
let _ = subject;
Ok(SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or(Duration::ZERO)
.as_millis() as i64)
})
}
fn set_offset<'a>(
&'a self,
_subject: &'a Subject,
_offset_ms: i64,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move { Err(NOT_SUPPORTED.to_string()) })
}
fn advance<'a>(
&'a self,
_subject: &'a Subject,
_delta_ms: i64,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move { Err(NOT_SUPPORTED.to_string()) })
}
fn set_rate<'a>(
&'a self,
_subject: &'a Subject,
_rate: f64,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move { Err(NOT_SUPPORTED.to_string()) })
}
fn freeze<'a>(
&'a self,
_subject: &'a Subject,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move { Err(NOT_SUPPORTED.to_string()) })
}
fn release<'a>(
&'a self,
_subject: &'a Subject,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move { Err(NOT_SUPPORTED.to_string()) })
}
fn state<'a>(
&'a self,
_subject: &'a Subject,
) -> Pin<Box<dyn Future<Output = Result<ClockState, String>> + Send + 'a>> {
Box::pin(async move { Err(NOT_SUPPORTED.to_string()) })
}
}