use crate::base::serial::Serial;
use serde::{Deserialize, Serialize};
use std::vec::Vec;
#[derive(
Clone,
Copy,
Debug,
Deserialize,
Eq,
Hash,
PartialEq,
PartialOrd,
Serialize,
)]
pub struct Version(Serial);
impl Version {
pub fn next(self) -> Version {
Version(self.0.add(1))
}
}
impl Default for Version {
fn default() -> Self {
Version(0.into())
}
}
#[derive(Clone, Debug)]
pub struct Versioned<T> {
data: Vec<(Version, Option<T>)>,
}
impl<T> Versioned<T> {
pub fn new() -> Self {
Versioned { data: Vec::new() }
}
pub fn get(&self, version: Version) -> Option<&T> {
let res = self.data.iter().rev().find_map(|item| {
if item.0 <= version {
Some(item.1.as_ref())
} else {
None
}
});
res.flatten()
}
pub fn update(&mut self, version: Version, value: T) {
if let Some(last) = self.data.last_mut() {
if last.0 == version {
last.1 = Some(value);
return;
}
}
self.data.push((version, Some(value)))
}
pub fn rollback(&mut self, version: Version) {
if self.data.last().map(|item| item.0) == Some(version) {
self.data.pop();
}
}
pub fn remove(&mut self, version: Version) {
let len = self.data.len();
if let Some(last) = self.data.last_mut() {
if last.1.is_none() {
return;
}
if last.0 == version {
if len == 1 {
let _ = self.data.pop();
} else {
last.1 = None;
}
return;
}
}
if !self.data.is_empty() {
self.data.push((version, None))
}
}
}
impl<T> Default for Versioned<T> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct VersionMarker;