Skip to main content

relay_knowledge/storage/contracts/
topology.rs

1use serde::{Deserialize, Serialize};
2
3use super::StorageError;
4
5/// Storage topology selected at runtime.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum StorageTopology {
8    SingleSqlite,
9    PartitionedSqlite,
10}
11
12impl StorageTopology {
13    pub const fn as_str(self) -> &'static str {
14        match self {
15            Self::SingleSqlite => "single_sqlite",
16            Self::PartitionedSqlite => "partitioned_sqlite",
17        }
18    }
19
20    pub fn parse(value: &str) -> Result<Self, StorageError> {
21        match value.trim().to_ascii_lowercase().as_str() {
22            "" | "single" | "single_sqlite" | "sqlite" => Ok(Self::SingleSqlite),
23            "partitioned" | "partitioned_sqlite" | "sqlite_partitioned" => {
24                Ok(Self::PartitionedSqlite)
25            }
26            other => Err(StorageError::InvalidInput(format!(
27                "storage topology '{other}' must be single_sqlite or partitioned_sqlite"
28            ))),
29        }
30    }
31}
32
33/// Runtime storage topology snapshot surfaced through service diagnostics.
34#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
35pub struct StorageTopologySnapshot {
36    pub shards: Vec<StorageShardCatalogEntry>,
37}
38
39/// One repository shard entry from the partitioned SQLite catalog.
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
41pub struct StorageShardCatalogEntry {
42    pub repository_id: String,
43    pub state: String,
44    pub shard_locator: String,
45    pub resolved_path: String,
46    pub source_scope_count: usize,
47    pub exists: bool,
48    pub updated_at_ms: u64,
49}
50
51#[cfg(test)]
52#[path = "topology_tests.rs"]
53mod tests;