use std::collections::VecDeque;
use std::time::SystemTime;
const DEFAULT_CAPACITY: usize = 200;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CommandStatus {
Success,
Failed,
}
#[derive(Debug, Clone)]
pub struct CommandRecord {
pub operation: String,
pub args: Vec<String>,
pub timestamp: SystemTime,
pub duration_ms: u128,
pub status: CommandStatus,
pub error: Option<String>,
}
#[derive(Debug)]
pub struct CommandHistory {
records: VecDeque<CommandRecord>,
capacity: usize,
}
impl Default for CommandHistory {
fn default() -> Self {
Self::new()
}
}
impl CommandHistory {
pub fn new() -> Self {
Self {
records: VecDeque::new(),
capacity: DEFAULT_CAPACITY,
}
}
pub fn push(&mut self, record: CommandRecord) {
if self.records.len() >= self.capacity {
self.records.pop_front();
}
self.records.push_back(record);
}
pub fn records(&self) -> &VecDeque<CommandRecord> {
&self.records
}
pub fn len(&self) -> usize {
self.records.len()
}
pub fn is_empty(&self) -> bool {
self.records.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_record(operation: &str, status: CommandStatus) -> CommandRecord {
CommandRecord {
operation: operation.to_string(),
args: vec!["test".to_string()],
timestamp: SystemTime::now(),
duration_ms: 42,
status,
error: None,
}
}
#[test]
fn test_push_and_capacity() {
let mut history = CommandHistory {
records: VecDeque::new(),
capacity: 3,
};
for i in 0..5 {
history.push(make_record(&format!("op{}", i), CommandStatus::Success));
}
assert_eq!(history.len(), 3);
assert_eq!(history.records()[0].operation, "op2");
assert_eq!(history.records()[1].operation, "op3");
assert_eq!(history.records()[2].operation, "op4");
}
#[test]
fn test_records_order() {
let mut history = CommandHistory::new();
history.push(make_record("first", CommandStatus::Success));
history.push(make_record("second", CommandStatus::Failed));
assert_eq!(history.records().len(), 2);
assert_eq!(history.records()[0].operation, "first");
assert_eq!(history.records()[1].operation, "second");
}
#[test]
fn test_empty_history() {
let history = CommandHistory::new();
assert!(history.is_empty());
assert_eq!(history.len(), 0);
}
}