Skip to main content

oxgraph_postgres/
status.rs

1//! JSON status payloads for admin and discovery surfaces.
2
3use crate::{Engine, SyncHealth};
4
5/// Engine status JSON payload for admin surfaces.
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct EngineStatusReport {
8    /// Whether an engine is loaded in this backend.
9    pub loaded: bool,
10    /// Node count from artifact metadata.
11    pub node_count: u32,
12    /// Edge count from artifact metadata.
13    pub edge_count: u32,
14    /// Whether the artifact is read-only.
15    pub read_only: bool,
16    /// Overlay edge insertions currently buffered.
17    pub overlay_edge_count: usize,
18    /// Tombstoned base edges.
19    pub tombstoned_edges: usize,
20    /// Sync overlay edge count.
21    pub sync_overlay_edges: usize,
22    /// Sync tombstoned edge count.
23    pub sync_tombstoned_edges: usize,
24    /// Sync tombstoned node count.
25    pub sync_tombstoned_nodes: usize,
26}
27
28impl EngineStatusReport {
29    /// Builds a report for an unloaded session.
30    #[must_use]
31    pub const fn unloaded() -> Self {
32        Self {
33            loaded: false,
34            node_count: 0,
35            edge_count: 0,
36            read_only: false,
37            overlay_edge_count: 0,
38            tombstoned_edges: 0,
39            sync_overlay_edges: 0,
40            sync_tombstoned_edges: 0,
41            sync_tombstoned_nodes: 0,
42        }
43    }
44
45    /// Builds a report from a loaded engine.
46    #[must_use]
47    pub fn from_engine(engine: &Engine) -> Self {
48        let status = engine.stats();
49        let health = engine.sync_health();
50        Self {
51            loaded: true,
52            node_count: status.node_count,
53            edge_count: status.edge_count,
54            read_only: status.read_only,
55            overlay_edge_count: status.overlay_edge_count,
56            tombstoned_edges: status.tombstoned_edges,
57            sync_overlay_edges: health.overlay_edges,
58            sync_tombstoned_edges: health.tombstoned_edges,
59            sync_tombstoned_nodes: health.tombstoned_nodes,
60        }
61    }
62
63    /// Serializes this report as compact JSON.
64    ///
65    /// # Performance
66    ///
67    /// This method is `O(1)`.
68    #[must_use]
69    pub fn to_json(&self) -> alloc::string::String {
70        if !self.loaded {
71            return "{\"loaded\":false}".into();
72        }
73        alloc::format!(
74            "{{\"loaded\":true,\"node_count\":{},\"edge_count\":{},\"read_only\":{},\
75\"overlay_edge_count\":{},\"tombstoned_edges\":{},\"sync_overlay_edges\":{},\
76\"sync_tombstoned_edges\":{},\"sync_tombstoned_nodes\":{}}}",
77            self.node_count,
78            self.edge_count,
79            self.read_only,
80            self.overlay_edge_count,
81            self.tombstoned_edges,
82            self.sync_overlay_edges,
83            self.sync_tombstoned_edges,
84            self.sync_tombstoned_nodes
85        )
86    }
87}
88
89/// Sync health JSON payload.
90#[derive(Clone, Copy, Debug, PartialEq, Eq)]
91pub struct SyncHealthReport {
92    /// Overlay edge insertions currently buffered.
93    pub overlay_edges: usize,
94    /// Tombstoned base edges.
95    pub tombstoned_edges: usize,
96    /// Tombstoned nodes.
97    pub tombstoned_nodes: usize,
98}
99
100impl From<SyncHealth> for SyncHealthReport {
101    fn from(health: SyncHealth) -> Self {
102        Self {
103            overlay_edges: health.overlay_edges,
104            tombstoned_edges: health.tombstoned_edges,
105            tombstoned_nodes: health.tombstoned_nodes,
106        }
107    }
108}
109
110impl SyncHealthReport {
111    /// Serializes this report as compact JSON.
112    ///
113    /// # Performance
114    ///
115    /// This method is `O(1)`.
116    #[must_use]
117    pub fn to_json(&self) -> alloc::string::String {
118        alloc::format!(
119            "{{\"overlay_edges\":{},\"tombstoned_edges\":{},\"tombstoned_nodes\":{}}}",
120            self.overlay_edges,
121            self.tombstoned_edges,
122            self.tombstoned_nodes
123        )
124    }
125}