Skip to main content

a3s_memory/repository/
access.rs

1use super::validation::{validate_required_text, MAX_IDENTIFIER_BYTES};
2use super::{MemoryNamespace, MemoryNode, MemoryRepositoryError};
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6/// Explicit observation supplied after retrieval by an authorized host.
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct MemoryAccessEvent {
10    pub id: String,
11    pub namespace: MemoryNamespace,
12    pub node_id: String,
13    pub node_revision: u64,
14    pub occurred_at: DateTime<Utc>,
15    pub context_id: Option<String>,
16}
17
18impl MemoryAccessEvent {
19    pub fn new(
20        id: impl Into<String>,
21        namespace: MemoryNamespace,
22        node_id: impl Into<String>,
23        node_revision: u64,
24        occurred_at: DateTime<Utc>,
25    ) -> Self {
26        Self {
27            id: id.into(),
28            namespace,
29            node_id: node_id.into(),
30            node_revision,
31            occurred_at,
32            context_id: None,
33        }
34    }
35
36    pub fn with_context_id(mut self, context_id: impl Into<String>) -> Self {
37        self.context_id = Some(context_id.into());
38        self
39    }
40
41    pub(crate) fn validate(&self) -> Result<(), MemoryRepositoryError> {
42        self.namespace.validate()?;
43        validate_required_text("accessEvent.id", &self.id, MAX_IDENTIFIER_BYTES)?;
44        validate_required_text("accessEvent.nodeId", &self.node_id, MAX_IDENTIFIER_BYTES)?;
45        if self.node_revision == 0 {
46            return Err(MemoryRepositoryError::invalid(
47                "accessEvent.nodeRevision",
48                "must be greater than zero",
49            ));
50        }
51        if let Some(context_id) = &self.context_id {
52            validate_required_text("accessEvent.contextId", context_id, MAX_IDENTIFIER_BYTES)?;
53        }
54        Ok(())
55    }
56}
57
58#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
59#[serde(rename_all = "camelCase")]
60pub struct MemoryUsageSummary {
61    pub admissions: u64,
62    pub uses: u64,
63}
64
65/// Deterministically ordered diagnostic snapshot of the reference repository.
66#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
67#[serde(rename_all = "camelCase")]
68pub struct MemoryRepositorySnapshot {
69    pub nodes: Vec<MemoryNode>,
70    pub admissions: Vec<MemoryAccessEvent>,
71    pub uses: Vec<MemoryAccessEvent>,
72}