#[cfg(not(target_family = "wasm"))]
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use std::{cmp::max, sync::Arc, time::Duration};
#[cfg(target_family = "wasm")]
use web_time::{Instant, SystemTime, UNIX_EPOCH};
#[derive(Clone, PartialEq, Eq)]
pub struct ObjectState<T> {
pub data: T,
pub format: DataFormat,
pub version: DataVersion,
pub synchronized: DataSynchronized,
}
pub type DataVersion = Vec<i64>;
pub type DataFormat = Vec<String>;
pub type DataBytes = Arc<Vec<u8>>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum DataSynchronized {
Now,
LastAt(Instant),
}
impl DataSynchronized {
pub fn micros_ago(&self) -> u64 {
match self {
DataSynchronized::LastAt(timestamp) => {
max(1, (Instant::now().checked_duration_since(*timestamp)).map(|duration| duration.as_micros()).unwrap_or(1) as u64)
}
DataSynchronized::Now => 0,
}
}
pub fn from_micros_ago(micros_ago: u64) -> DataSynchronized {
if micros_ago == 0 {
DataSynchronized::Now
} else {
DataSynchronized::LastAt(Instant::now().checked_sub(Duration::from_micros(micros_ago)).unwrap_or(Instant::now()))
}
}
}
impl<T: 'static> ObjectState<T> {
pub fn new(data: T) -> ObjectState<T> {
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
ObjectState {
data,
format: vec![],
version: vec![0, (timestamp / 1000000000) as i64, (timestamp % 1000000000) as i64],
synchronized: DataSynchronized::Now,
}
}
pub fn with_data<U>(self, data: U) -> ObjectState<U> {
ObjectState { data, version: self.version, format: self.format, synchronized: self.synchronized }
}
pub fn with_version(mut self, version: impl Into<DataVersion>) -> ObjectState<T> {
self.version = version.into();
self
}
pub fn with_format(mut self, format: impl Into<DataFormat>) -> ObjectState<T> {
self.format = format.into();
self
}
pub fn with_synchronized(mut self, synchronized: impl Into<DataSynchronized>) -> ObjectState<T> {
self.synchronized = synchronized.into();
self
}
}