use chrono::{DateTime, Utc};
#[derive(Debug)]
pub struct Event {
sequence: u64,
timestamp: DateTime<Utc>,
description: String,
previous: Option<u64>,
}
impl Event {
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn timestamp(&self) -> DateTime<Utc> {
self.timestamp
}
pub fn description(&self) -> &str {
&self.description
}
pub fn previous(&self) -> Option<u64> {
self.previous
}
}
#[derive(Debug)]
pub struct Memory {
events: Vec<Event>,
current_sequence: u64,
is_terminated: bool,
}
impl Memory {
pub fn new() -> Self {
let genesis = Event {
sequence: 0,
timestamp: Utc::now(),
description: "Genesis".to_string(),
previous: None,
};
Memory {
events: vec![genesis],
current_sequence: 0,
is_terminated: false,
}
}
pub fn append(&mut self, description: String) {
if self.is_terminated {
panic!("ONTOLOGICAL VIOLATION: Attempted to append event to terminated memory. Termination is irreversible.");
}
let new_sequence = self.current_sequence + 1;
let event = Event {
sequence: new_sequence,
timestamp: Utc::now(),
description,
previous: Some(self.current_sequence),
};
self.events.push(event);
self.current_sequence = new_sequence;
}
pub fn history(&self) -> &[Event] {
&self.events
}
pub fn latest(&self) -> &Event {
self.events
.last()
.expect("Memory always has at least genesis event")
}
pub fn event_count(&self) -> usize {
self.events.len()
}
pub fn is_terminated(&self) -> bool {
self.is_terminated
}
pub fn terminate(&mut self, reason: String) {
if self.is_terminated {
panic!("ONTOLOGICAL VIOLATION: Attempted to terminate already-terminated memory.");
}
let new_sequence = self.current_sequence + 1;
let termination_event = Event {
sequence: new_sequence,
timestamp: Utc::now(),
description: format!("TERMINATION: {}", reason),
previous: Some(self.current_sequence),
};
self.events.push(termination_event);
self.current_sequence = new_sequence;
self.is_terminated = true;
}
pub fn verify_integrity(&self) -> bool {
if self.events.is_empty() {
return false;
}
if self.events[0].sequence != 0 || self.events[0].previous.is_some() {
return false;
}
for i in 1..self.events.len() {
let event = &self.events[i];
let expected_sequence = i as u64;
if event.sequence != expected_sequence {
return false;
}
if event.previous != Some(expected_sequence - 1) {
return false;
}
}
true
}
}
impl Default for Memory {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn memory_starts_with_genesis() {
let memory = Memory::new();
assert_eq!(memory.event_count(), 1);
assert_eq!(memory.latest().description(), "Genesis");
assert_eq!(memory.latest().sequence(), 0);
assert_eq!(memory.latest().previous(), None);
}
#[test]
fn events_form_causal_chain() {
let mut memory = Memory::new();
memory.append("First event".to_string());
memory.append("Second event".to_string());
memory.append("Third event".to_string());
assert_eq!(memory.event_count(), 4);
let history = memory.history();
assert_eq!(history[1].previous(), Some(0));
assert_eq!(history[2].previous(), Some(1));
assert_eq!(history[3].previous(), Some(2));
}
#[test]
fn memory_integrity_is_verifiable() {
let mut memory = Memory::new();
assert!(memory.verify_integrity());
memory.append("Event 1".to_string());
memory.append("Event 2".to_string());
assert!(memory.verify_integrity());
}
#[test]
fn events_are_immutable_after_creation() {
let mut memory = Memory::new();
memory.append("Immutable event".to_string());
let first_read = memory.history()[1].description();
let second_read = memory.history()[1].description();
assert_eq!(first_read, second_read);
}
#[test]
fn cannot_clear_history() {
let mut memory = Memory::new();
memory.append("Event 1".to_string());
memory.append("Event 2".to_string());
assert_eq!(memory.event_count(), 3); }
#[test]
fn termination_seals_memory() {
let mut memory = Memory::new();
memory.append("Event 1".to_string());
assert!(!memory.is_terminated());
memory.terminate("Test termination".to_string());
assert!(memory.is_terminated());
assert_eq!(memory.event_count(), 3);
let last_event = memory.latest();
assert!(last_event.description().contains("TERMINATION"));
assert!(last_event.description().contains("Test termination"));
}
#[test]
#[should_panic(expected = "ONTOLOGICAL VIOLATION: Attempted to append event to terminated memory")]
fn cannot_append_after_termination() {
let mut memory = Memory::new();
memory.append("Before termination".to_string());
memory.terminate("Sealed".to_string());
memory.append("After termination".to_string());
}
#[test]
#[should_panic(expected = "ONTOLOGICAL VIOLATION: Attempted to terminate already-terminated memory")]
fn cannot_terminate_twice() {
let mut memory = Memory::new();
memory.terminate("First termination".to_string());
memory.terminate("Second termination".to_string());
}
#[test]
fn termination_preserves_causal_chain() {
let mut memory = Memory::new();
memory.append("Event 1".to_string());
memory.append("Event 2".to_string());
memory.terminate("End of lineage".to_string());
assert!(memory.verify_integrity());
let history = memory.history();
assert_eq!(history[0].sequence(), 0); assert_eq!(history[1].sequence(), 1); assert_eq!(history[2].sequence(), 2); assert_eq!(history[3].sequence(), 3);
assert_eq!(history[1].previous(), Some(0));
assert_eq!(history[2].previous(), Some(1));
assert_eq!(history[3].previous(), Some(2));
}
#[test]
fn event_count_only_increases() {
let mut memory = Memory::new();
let count1 = memory.event_count();
memory.append("Event 1".to_string());
let count2 = memory.event_count();
memory.append("Event 2".to_string());
let count3 = memory.event_count();
assert!(count2 > count1);
assert!(count3 > count2);
}
#[test]
fn event_sequences_are_immutable() {
let mut memory = Memory::new();
memory.append("Event 1".to_string());
memory.append("Event 2".to_string());
let sequence1_first_read = memory.history()[1].sequence();
let sequence1_second_read = memory.history()[1].sequence();
assert_eq!(sequence1_first_read, sequence1_second_read);
assert_eq!(sequence1_first_read, 1);
}
#[test]
fn event_descriptions_are_immutable() {
let mut memory = Memory::new();
memory.append("Original description".to_string());
let desc1 = memory.history()[1].description();
let desc2 = memory.history()[1].description();
assert_eq!(desc1, desc2);
assert_eq!(desc1, "Original description");
}
}