45 lines
1.2 KiB
Rust
45 lines
1.2 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)]
|
||
|
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 + std::cmp::PartialEq> 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,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Update the value. The change will be recorded.
|
||
|
pub fn update(&mut self, value: T) {
|
||
|
if self.current == value {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
self.changes
|
||
|
.insert(chrono::Utc::now().to_rfc3339(), value.clone());
|
||
|
self.current = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<T> Deref for Historic<T> {
|
||
|
type Target = T;
|
||
|
|
||
|
fn deref(&self) -> &Self::Target {
|
||
|
&self.current
|
||
|
}
|
||
|
}
|