mongod/src/model/historic.rs
2024-09-11 11:09:38 +02:00

62 lines
1.7 KiB
Rust

use serde::{Deserialize, Serialize};
use std::{collections::HashMap, ops::Deref};
/// A struct to keep track of historical changes to a value.
/// This struct represents a value that has a current state and a history of previous states.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Historic<T> {
/// The current value
pub current: T,
/// A map of timestamps (RFC 3339) to historical values.
pub changes: HashMap<String, T>,
}
impl<T: Clone> Historic<T> {
/// Create a new value with tracked history
pub fn new(value: T) -> Historic<T> {
let mut changes = HashMap::new();
changes.insert(chrono::Utc::now().to_rfc3339(), value.clone());
Self {
current: value,
changes,
}
}
}
impl<T: Default + Clone> Historic<T> {
/// Create a new tracked value initialized with Default
pub fn new_default() -> Historic<T> {
Self::new(T::default())
}
}
impl<T: Clone> Historic<T> {
/// Update the value. The change will be recorded.
/// Will record a change even if the value is the same as the current one.
pub fn update(&mut self, value: T) {
self.changes
.insert(chrono::Utc::now().to_rfc3339(), value.clone());
self.current = value;
}
}
impl<T: Clone + std::cmp::PartialEq> Historic<T> {
/// Update the value. The change will be recorded.
/// If the value is equal to the current one, no update will take place.
pub fn update_unique(&mut self, value: T) {
if self.current == value {
return;
}
self.update(value);
}
}
impl<T> Deref for Historic<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.current
}
}