envx_core/
history.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum HistoryAction {
6    Set {
7        name: String,
8        old_value: Option<String>,
9        new_value: String,
10    },
11    Delete {
12        name: String,
13        old_value: String,
14    },
15    BatchUpdate {
16        changes: Vec<(String, Option<String>, String)>,
17    },
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct HistoryEntry {
22    pub id: uuid::Uuid,
23    pub timestamp: DateTime<Utc>,
24    pub action: HistoryAction,
25}
26
27impl HistoryEntry {
28    #[must_use]
29    pub fn new(action: HistoryAction) -> Self {
30        Self {
31            id: uuid::Uuid::new_v4(),
32            timestamp: Utc::now(),
33            action,
34        }
35    }
36}
37
38#[derive(Debug, Default)]
39pub struct History {
40    entries: Vec<HistoryEntry>,
41    max_entries: usize,
42}
43
44impl History {
45    #[must_use]
46    pub const fn new(max_entries: usize) -> Self {
47        Self {
48            entries: Vec::new(),
49            max_entries,
50        }
51    }
52
53    pub fn add(&mut self, entry: HistoryEntry) {
54        self.entries.push(entry);
55        if self.entries.len() > self.max_entries {
56            self.entries.remove(0);
57        }
58    }
59
60    #[must_use]
61    pub fn recent(&self, count: usize) -> Vec<&HistoryEntry> {
62        self.entries.iter().rev().take(count).collect()
63    }
64
65    pub fn clear(&mut self) {
66        self.entries.clear();
67    }
68}