Skip to main content

icydb_core/db/diagnostics/
model.rs

1//! Module: diagnostics::model
2//! Responsibility: diagnostics report DTO contracts and simple accessors.
3//! Does not own: store traversal, integrity scanning, or execution trace policy.
4//! Boundary: report assembly modules construct these DTOs; public callers read them.
5
6use crate::db::{
7    index::IndexState,
8    registry::{
9        StoreAllocationIdentityCapability, StoreCommitParticipation, StoreDurability,
10        StoreRecoveryCapability, StoreRuntimeStorageCapabilities, StoreSchemaMetadataCapability,
11    },
12};
13use candid::CandidType;
14use serde::Deserialize;
15
16#[cfg_attr(doc, doc = "StorageReport\n\nLive storage snapshot payload.")]
17#[derive(CandidType, Clone, Debug, Default, Deserialize)]
18pub struct StorageReport {
19    pub(crate) storage_data: Vec<DataStoreSnapshot>,
20    pub(crate) storage_index: Vec<IndexStoreSnapshot>,
21    pub(crate) schema_storage: Vec<SchemaStoreSnapshot>,
22    pub(crate) entity_storage: Vec<EntitySnapshot>,
23    pub(crate) corrupted_keys: u64,
24    pub(crate) corrupted_entries: u64,
25}
26
27#[cfg_attr(
28    doc,
29    doc = "IntegrityTotals\n\nAggregated integrity-scan counters across all stores."
30)]
31#[derive(CandidType, Clone, Debug, Default, Deserialize)]
32pub struct IntegrityTotals {
33    pub(crate) data_rows_scanned: u64,
34    pub(crate) index_entries_scanned: u64,
35    pub(crate) corrupted_data_keys: u64,
36    pub(crate) corrupted_data_rows: u64,
37    pub(crate) corrupted_index_keys: u64,
38    pub(crate) corrupted_index_entries: u64,
39    pub(crate) missing_index_entries: u64,
40    pub(crate) divergent_index_entries: u64,
41    pub(crate) orphan_index_references: u64,
42    pub(crate) misuse_findings: u64,
43}
44
45impl IntegrityTotals {
46    pub(super) const fn add_store_snapshot(&mut self, store: &IntegrityStoreSnapshot) {
47        self.data_rows_scanned = self
48            .data_rows_scanned
49            .saturating_add(store.data_rows_scanned);
50        self.index_entries_scanned = self
51            .index_entries_scanned
52            .saturating_add(store.index_entries_scanned);
53        self.corrupted_data_keys = self
54            .corrupted_data_keys
55            .saturating_add(store.corrupted_data_keys);
56        self.corrupted_data_rows = self
57            .corrupted_data_rows
58            .saturating_add(store.corrupted_data_rows);
59        self.corrupted_index_keys = self
60            .corrupted_index_keys
61            .saturating_add(store.corrupted_index_keys);
62        self.corrupted_index_entries = self
63            .corrupted_index_entries
64            .saturating_add(store.corrupted_index_entries);
65        self.missing_index_entries = self
66            .missing_index_entries
67            .saturating_add(store.missing_index_entries);
68        self.divergent_index_entries = self
69            .divergent_index_entries
70            .saturating_add(store.divergent_index_entries);
71        self.orphan_index_references = self
72            .orphan_index_references
73            .saturating_add(store.orphan_index_references);
74        self.misuse_findings = self.misuse_findings.saturating_add(store.misuse_findings);
75    }
76
77    /// Return total number of data rows scanned.
78    #[must_use]
79    pub const fn data_rows_scanned(&self) -> u64 {
80        self.data_rows_scanned
81    }
82
83    /// Return total number of index entries scanned.
84    #[must_use]
85    pub const fn index_entries_scanned(&self) -> u64 {
86        self.index_entries_scanned
87    }
88
89    /// Return total number of corrupted data-key findings.
90    #[must_use]
91    pub const fn corrupted_data_keys(&self) -> u64 {
92        self.corrupted_data_keys
93    }
94
95    /// Return total number of corrupted data-row findings.
96    #[must_use]
97    pub const fn corrupted_data_rows(&self) -> u64 {
98        self.corrupted_data_rows
99    }
100
101    /// Return total number of corrupted index-key findings.
102    #[must_use]
103    pub const fn corrupted_index_keys(&self) -> u64 {
104        self.corrupted_index_keys
105    }
106
107    /// Return total number of corrupted index-entry findings.
108    #[must_use]
109    pub const fn corrupted_index_entries(&self) -> u64 {
110        self.corrupted_index_entries
111    }
112
113    /// Return total number of missing index-entry findings.
114    #[must_use]
115    pub const fn missing_index_entries(&self) -> u64 {
116        self.missing_index_entries
117    }
118
119    /// Return total number of divergent index-entry findings.
120    #[must_use]
121    pub const fn divergent_index_entries(&self) -> u64 {
122        self.divergent_index_entries
123    }
124
125    /// Return total number of orphan index-reference findings.
126    #[must_use]
127    pub const fn orphan_index_references(&self) -> u64 {
128        self.orphan_index_references
129    }
130
131    /// Return total number of misuse findings.
132    #[must_use]
133    pub const fn misuse_findings(&self) -> u64 {
134        self.misuse_findings
135    }
136}
137
138#[cfg_attr(
139    doc,
140    doc = "IntegrityStoreSnapshot\n\nPer-store integrity findings and scan counters."
141)]
142#[derive(CandidType, Clone, Debug, Default, Deserialize)]
143pub struct IntegrityStoreSnapshot {
144    pub(crate) path: String,
145    pub(crate) data_rows_scanned: u64,
146    pub(crate) index_entries_scanned: u64,
147    pub(crate) corrupted_data_keys: u64,
148    pub(crate) corrupted_data_rows: u64,
149    pub(crate) corrupted_index_keys: u64,
150    pub(crate) corrupted_index_entries: u64,
151    pub(crate) missing_index_entries: u64,
152    pub(crate) divergent_index_entries: u64,
153    pub(crate) orphan_index_references: u64,
154    pub(crate) misuse_findings: u64,
155}
156
157impl IntegrityStoreSnapshot {
158    /// Construct one empty store-level integrity snapshot.
159    #[must_use]
160    pub(crate) fn new(path: String) -> Self {
161        Self {
162            path,
163            ..Self::default()
164        }
165    }
166
167    /// Borrow store path.
168    #[must_use]
169    pub const fn path(&self) -> &str {
170        self.path.as_str()
171    }
172
173    /// Return number of scanned data rows.
174    #[must_use]
175    pub const fn data_rows_scanned(&self) -> u64 {
176        self.data_rows_scanned
177    }
178
179    /// Return number of scanned index entries.
180    #[must_use]
181    pub const fn index_entries_scanned(&self) -> u64 {
182        self.index_entries_scanned
183    }
184
185    /// Return number of corrupted data-key findings.
186    #[must_use]
187    pub const fn corrupted_data_keys(&self) -> u64 {
188        self.corrupted_data_keys
189    }
190
191    /// Return number of corrupted data-row findings.
192    #[must_use]
193    pub const fn corrupted_data_rows(&self) -> u64 {
194        self.corrupted_data_rows
195    }
196
197    /// Return number of corrupted index-key findings.
198    #[must_use]
199    pub const fn corrupted_index_keys(&self) -> u64 {
200        self.corrupted_index_keys
201    }
202
203    /// Return number of corrupted index-entry findings.
204    #[must_use]
205    pub const fn corrupted_index_entries(&self) -> u64 {
206        self.corrupted_index_entries
207    }
208
209    /// Return number of missing index-entry findings.
210    #[must_use]
211    pub const fn missing_index_entries(&self) -> u64 {
212        self.missing_index_entries
213    }
214
215    /// Return number of divergent index-entry findings.
216    #[must_use]
217    pub const fn divergent_index_entries(&self) -> u64 {
218        self.divergent_index_entries
219    }
220
221    /// Return number of orphan index-reference findings.
222    #[must_use]
223    pub const fn orphan_index_references(&self) -> u64 {
224        self.orphan_index_references
225    }
226
227    /// Return number of misuse findings.
228    #[must_use]
229    pub const fn misuse_findings(&self) -> u64 {
230        self.misuse_findings
231    }
232}
233
234#[cfg_attr(
235    doc,
236    doc = "IntegrityReport\n\nFull integrity-scan output across all registered stores."
237)]
238#[derive(CandidType, Clone, Debug, Default, Deserialize)]
239pub struct IntegrityReport {
240    pub(crate) stores: Vec<IntegrityStoreSnapshot>,
241    pub(crate) totals: IntegrityTotals,
242}
243
244impl IntegrityReport {
245    /// Construct one integrity report payload.
246    #[must_use]
247    pub(crate) const fn new(stores: Vec<IntegrityStoreSnapshot>, totals: IntegrityTotals) -> Self {
248        Self { stores, totals }
249    }
250
251    /// Borrow per-store integrity snapshots.
252    #[must_use]
253    pub const fn stores(&self) -> &[IntegrityStoreSnapshot] {
254        self.stores.as_slice()
255    }
256
257    /// Borrow aggregated integrity totals.
258    #[must_use]
259    pub const fn totals(&self) -> &IntegrityTotals {
260        &self.totals
261    }
262}
263
264impl StorageReport {
265    /// Construct one storage report payload.
266    #[must_use]
267    pub(crate) const fn new(
268        storage_data: Vec<DataStoreSnapshot>,
269        storage_index: Vec<IndexStoreSnapshot>,
270        schema_storage: Vec<SchemaStoreSnapshot>,
271        entity_storage: Vec<EntitySnapshot>,
272        corrupted_keys: u64,
273        corrupted_entries: u64,
274    ) -> Self {
275        Self {
276            storage_data,
277            storage_index,
278            schema_storage,
279            entity_storage,
280            corrupted_keys,
281            corrupted_entries,
282        }
283    }
284
285    /// Borrow data-store snapshots.
286    #[must_use]
287    pub const fn storage_data(&self) -> &[DataStoreSnapshot] {
288        self.storage_data.as_slice()
289    }
290
291    /// Borrow index-store snapshots.
292    #[must_use]
293    pub const fn storage_index(&self) -> &[IndexStoreSnapshot] {
294        self.storage_index.as_slice()
295    }
296
297    /// Borrow schema-store snapshots.
298    #[must_use]
299    pub const fn schema_storage(&self) -> &[SchemaStoreSnapshot] {
300        self.schema_storage.as_slice()
301    }
302
303    /// Borrow entity-level storage snapshots.
304    #[must_use]
305    pub const fn entity_storage(&self) -> &[EntitySnapshot] {
306        self.entity_storage.as_slice()
307    }
308
309    /// Return count of corrupted decoded data keys.
310    #[must_use]
311    pub const fn corrupted_keys(&self) -> u64 {
312        self.corrupted_keys
313    }
314
315    /// Return count of corrupted index entries.
316    #[must_use]
317    pub const fn corrupted_entries(&self) -> u64 {
318        self.corrupted_entries
319    }
320}
321
322#[cfg_attr(doc, doc = "SchemaStoreSnapshot\n\nSchema-store diagnostic row.")]
323#[derive(CandidType, Clone, Debug, Default, Deserialize)]
324pub struct SchemaStoreSnapshot {
325    pub(crate) path: String,
326    pub(crate) storage: StoreSnapshotStorageMode,
327    pub(crate) allocation: StoreAllocationIdentityCapability,
328    pub(crate) durability: StoreDurability,
329    pub(crate) commit: StoreCommitParticipation,
330    pub(crate) recovery: StoreRecoveryCapability,
331    pub(crate) schema_metadata: StoreSchemaMetadataCapability,
332    pub(crate) memory_id: Option<u8>,
333    pub(crate) stable_key: Option<String>,
334    pub(crate) schema_version: Option<u32>,
335    pub(crate) schema_fingerprint: Option<String>,
336    pub(crate) entity_count: u64,
337}
338
339/// Diagnostic storage mode reported for one store-role snapshot.
340///
341/// This is observability metadata only. It does not participate in allocation
342/// identity, stable-key generation, or durable row/index/schema storage ABI.
343#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
344pub enum StoreSnapshotStorageMode {
345    #[default]
346    Stable,
347    Heap,
348}
349
350impl StoreSnapshotStorageMode {
351    /// Return the user-facing storage mode label.
352    #[must_use]
353    pub const fn as_str(self) -> &'static str {
354        match self {
355            Self::Stable => "stable",
356            Self::Heap => "heap",
357        }
358    }
359}
360
361#[derive(Clone, Debug, Eq, PartialEq)]
362pub(crate) struct StoreSnapshotAllocationIdentity {
363    memory_id: u8,
364    stable_key: String,
365}
366
367impl StoreSnapshotAllocationIdentity {
368    pub(crate) const fn new(memory_id: u8, stable_key: String) -> Self {
369        Self {
370            memory_id,
371            stable_key,
372        }
373    }
374
375    const fn memory_id(&self) -> u8 {
376        self.memory_id
377    }
378}
379
380#[derive(Clone, Debug, Default, Eq, PartialEq)]
381pub(crate) struct StoreSnapshotSchemaMetadata {
382    schema_version: Option<u32>,
383    schema_fingerprint: Option<String>,
384}
385
386impl StoreSnapshotSchemaMetadata {
387    pub(crate) const fn absent() -> Self {
388        Self {
389            schema_version: None,
390            schema_fingerprint: None,
391        }
392    }
393
394    pub(crate) const fn new(schema_version: u32, schema_fingerprint: String) -> Self {
395        Self {
396            schema_version: Some(schema_version),
397            schema_fingerprint: Some(schema_fingerprint),
398        }
399    }
400
401    const fn schema_version(&self) -> Option<u32> {
402        self.schema_version
403    }
404
405    fn schema_fingerprint(&self) -> Option<String> {
406        self.schema_fingerprint.clone()
407    }
408}
409
410#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
411pub(crate) struct IndexStoreSnapshotStats {
412    entries: u64,
413    user_entries: u64,
414    system_entries: u64,
415    memory_bytes: u64,
416    state: IndexState,
417}
418
419impl IndexStoreSnapshotStats {
420    pub(crate) const fn new(
421        entries: u64,
422        user_entries: u64,
423        system_entries: u64,
424        memory_bytes: u64,
425        state: IndexState,
426    ) -> Self {
427        Self {
428            entries,
429            user_entries,
430            system_entries,
431            memory_bytes,
432            state,
433        }
434    }
435}
436
437impl SchemaStoreSnapshot {
438    /// Construct one schema-store diagnostic row.
439    #[must_use]
440    pub(crate) fn new(
441        path: String,
442        storage: StoreSnapshotStorageMode,
443        capabilities: StoreRuntimeStorageCapabilities,
444        allocation: Option<StoreSnapshotAllocationIdentity>,
445        schema_metadata: StoreSnapshotSchemaMetadata,
446        entity_count: u64,
447    ) -> Self {
448        let memory_id = allocation
449            .as_ref()
450            .map(StoreSnapshotAllocationIdentity::memory_id);
451        let stable_key = match allocation {
452            Some(allocation) => Some(allocation.stable_key),
453            None => None,
454        };
455        Self {
456            path,
457            storage,
458            allocation: capabilities.allocation_identity(),
459            durability: capabilities.durability(),
460            commit: capabilities.commit_participation(),
461            recovery: capabilities.recovery(),
462            schema_metadata: capabilities.schema_metadata(),
463            memory_id,
464            stable_key,
465            schema_version: schema_metadata.schema_version(),
466            schema_fingerprint: schema_metadata.schema_fingerprint(),
467            entity_count,
468        }
469    }
470
471    /// Borrow store path.
472    #[must_use]
473    pub const fn path(&self) -> &str {
474        self.path.as_str()
475    }
476
477    /// Return diagnostic storage mode.
478    #[must_use]
479    pub const fn storage(&self) -> StoreSnapshotStorageMode {
480        self.storage
481    }
482
483    /// Return allocation-identity capability metadata.
484    #[must_use]
485    pub const fn allocation(&self) -> StoreAllocationIdentityCapability {
486        self.allocation
487    }
488
489    /// Return durability capability metadata.
490    #[must_use]
491    pub const fn durability(&self) -> StoreDurability {
492        self.durability
493    }
494
495    /// Return commit participation capability metadata.
496    #[must_use]
497    pub const fn commit(&self) -> StoreCommitParticipation {
498        self.commit
499    }
500
501    /// Return recovery capability metadata.
502    #[must_use]
503    pub const fn recovery(&self) -> StoreRecoveryCapability {
504        self.recovery
505    }
506
507    /// Return schema-metadata persistence capability metadata.
508    #[must_use]
509    pub const fn schema_metadata(&self) -> StoreSchemaMetadataCapability {
510        self.schema_metadata
511    }
512
513    /// Return stable-memory manager ID, when generated wiring supplied it.
514    #[must_use]
515    pub const fn memory_id(&self) -> Option<u8> {
516        self.memory_id
517    }
518
519    /// Return durable stable-memory key, when generated wiring supplied it.
520    #[must_use]
521    pub const fn stable_key(&self) -> Option<&str> {
522        match &self.stable_key {
523            Some(value) => Some(value.as_str()),
524            None => None,
525        }
526    }
527
528    /// Return accepted schema/catalog version, when known.
529    #[must_use]
530    pub const fn schema_version(&self) -> Option<u32> {
531        self.schema_version
532    }
533
534    /// Return accepted schema/catalog fingerprint, when known.
535    #[must_use]
536    pub const fn schema_fingerprint(&self) -> Option<&str> {
537        match &self.schema_fingerprint {
538            Some(value) => Some(value.as_str()),
539            None => None,
540        }
541    }
542
543    /// Return number of entity schemas represented in this schema catalog.
544    #[must_use]
545    pub const fn entity_count(&self) -> u64 {
546        self.entity_count
547    }
548}
549
550#[cfg_attr(doc, doc = "DataStoreSnapshot\n\nData-store snapshot row.")]
551#[derive(CandidType, Clone, Debug, Default, Deserialize)]
552pub struct DataStoreSnapshot {
553    pub(crate) path: String,
554    pub(crate) storage: StoreSnapshotStorageMode,
555    pub(crate) allocation: StoreAllocationIdentityCapability,
556    pub(crate) durability: StoreDurability,
557    pub(crate) commit: StoreCommitParticipation,
558    pub(crate) recovery: StoreRecoveryCapability,
559    pub(crate) schema_metadata: StoreSchemaMetadataCapability,
560    pub(crate) memory_id: Option<u8>,
561    pub(crate) stable_key: Option<String>,
562    pub(crate) schema_version: Option<u32>,
563    pub(crate) schema_fingerprint: Option<String>,
564    pub(crate) entries: u64,
565    pub(crate) memory_bytes: u64,
566}
567
568impl DataStoreSnapshot {
569    /// Construct one data-store snapshot row.
570    #[must_use]
571    pub(crate) fn new(
572        path: String,
573        storage: StoreSnapshotStorageMode,
574        capabilities: StoreRuntimeStorageCapabilities,
575        allocation: Option<StoreSnapshotAllocationIdentity>,
576        schema_metadata: StoreSnapshotSchemaMetadata,
577        entries: u64,
578        memory_bytes: u64,
579    ) -> Self {
580        let memory_id = allocation
581            .as_ref()
582            .map(StoreSnapshotAllocationIdentity::memory_id);
583        let stable_key = match allocation {
584            Some(allocation) => Some(allocation.stable_key),
585            None => None,
586        };
587        Self {
588            path,
589            storage,
590            allocation: capabilities.allocation_identity(),
591            durability: capabilities.durability(),
592            commit: capabilities.commit_participation(),
593            recovery: capabilities.recovery(),
594            schema_metadata: capabilities.schema_metadata(),
595            memory_id,
596            stable_key,
597            schema_version: schema_metadata.schema_version(),
598            schema_fingerprint: schema_metadata.schema_fingerprint(),
599            entries,
600            memory_bytes,
601        }
602    }
603
604    /// Borrow store path.
605    #[must_use]
606    pub const fn path(&self) -> &str {
607        self.path.as_str()
608    }
609
610    /// Return diagnostic storage mode.
611    #[must_use]
612    pub const fn storage(&self) -> StoreSnapshotStorageMode {
613        self.storage
614    }
615
616    /// Return allocation-identity capability metadata.
617    #[must_use]
618    pub const fn allocation(&self) -> StoreAllocationIdentityCapability {
619        self.allocation
620    }
621
622    /// Return durability capability metadata.
623    #[must_use]
624    pub const fn durability(&self) -> StoreDurability {
625        self.durability
626    }
627
628    /// Return commit participation capability metadata.
629    #[must_use]
630    pub const fn commit(&self) -> StoreCommitParticipation {
631        self.commit
632    }
633
634    /// Return recovery capability metadata.
635    #[must_use]
636    pub const fn recovery(&self) -> StoreRecoveryCapability {
637        self.recovery
638    }
639
640    /// Return schema-metadata persistence capability metadata.
641    #[must_use]
642    pub const fn schema_metadata(&self) -> StoreSchemaMetadataCapability {
643        self.schema_metadata
644    }
645
646    /// Return stable-memory manager ID, when generated wiring supplied it.
647    #[must_use]
648    pub const fn memory_id(&self) -> Option<u8> {
649        self.memory_id
650    }
651
652    /// Return durable stable-memory key, when generated wiring supplied it.
653    #[must_use]
654    pub const fn stable_key(&self) -> Option<&str> {
655        match &self.stable_key {
656            Some(value) => Some(value.as_str()),
657            None => None,
658        }
659    }
660
661    /// Return accepted schema/catalog version, when known.
662    #[must_use]
663    pub const fn schema_version(&self) -> Option<u32> {
664        self.schema_version
665    }
666
667    /// Return accepted schema/catalog fingerprint, when known.
668    #[must_use]
669    pub const fn schema_fingerprint(&self) -> Option<&str> {
670        match &self.schema_fingerprint {
671            Some(value) => Some(value.as_str()),
672            None => None,
673        }
674    }
675
676    /// Return row count.
677    #[must_use]
678    pub const fn entries(&self) -> u64 {
679        self.entries
680    }
681
682    /// Return memory usage in bytes.
683    #[must_use]
684    pub const fn memory_bytes(&self) -> u64 {
685        self.memory_bytes
686    }
687}
688
689#[cfg_attr(doc, doc = "IndexStoreSnapshot\n\nIndex-store snapshot row.")]
690#[derive(CandidType, Clone, Debug, Default, Deserialize)]
691pub struct IndexStoreSnapshot {
692    pub(crate) path: String,
693    pub(crate) storage: StoreSnapshotStorageMode,
694    pub(crate) allocation: StoreAllocationIdentityCapability,
695    pub(crate) durability: StoreDurability,
696    pub(crate) commit: StoreCommitParticipation,
697    pub(crate) recovery: StoreRecoveryCapability,
698    pub(crate) schema_metadata: StoreSchemaMetadataCapability,
699    pub(crate) memory_id: Option<u8>,
700    pub(crate) stable_key: Option<String>,
701    pub(crate) schema_version: Option<u32>,
702    pub(crate) schema_fingerprint: Option<String>,
703    pub(crate) entries: u64,
704    pub(crate) user_entries: u64,
705    pub(crate) system_entries: u64,
706    pub(crate) memory_bytes: u64,
707    pub(crate) state: IndexState,
708}
709
710impl IndexStoreSnapshot {
711    /// Construct one index-store snapshot row.
712    #[must_use]
713    pub(crate) fn new(
714        path: String,
715        storage: StoreSnapshotStorageMode,
716        capabilities: StoreRuntimeStorageCapabilities,
717        allocation: Option<StoreSnapshotAllocationIdentity>,
718        schema_metadata: StoreSnapshotSchemaMetadata,
719        stats: IndexStoreSnapshotStats,
720    ) -> Self {
721        let memory_id = allocation
722            .as_ref()
723            .map(StoreSnapshotAllocationIdentity::memory_id);
724        let stable_key = match allocation {
725            Some(allocation) => Some(allocation.stable_key),
726            None => None,
727        };
728        Self {
729            path,
730            storage,
731            allocation: capabilities.allocation_identity(),
732            durability: capabilities.durability(),
733            commit: capabilities.commit_participation(),
734            recovery: capabilities.recovery(),
735            schema_metadata: capabilities.schema_metadata(),
736            memory_id,
737            stable_key,
738            schema_version: schema_metadata.schema_version(),
739            schema_fingerprint: schema_metadata.schema_fingerprint(),
740            entries: stats.entries,
741            user_entries: stats.user_entries,
742            system_entries: stats.system_entries,
743            memory_bytes: stats.memory_bytes,
744            state: stats.state,
745        }
746    }
747
748    /// Borrow store path.
749    #[must_use]
750    pub const fn path(&self) -> &str {
751        self.path.as_str()
752    }
753
754    /// Return diagnostic storage mode.
755    #[must_use]
756    pub const fn storage(&self) -> StoreSnapshotStorageMode {
757        self.storage
758    }
759
760    /// Return allocation-identity capability metadata.
761    #[must_use]
762    pub const fn allocation(&self) -> StoreAllocationIdentityCapability {
763        self.allocation
764    }
765
766    /// Return durability capability metadata.
767    #[must_use]
768    pub const fn durability(&self) -> StoreDurability {
769        self.durability
770    }
771
772    /// Return commit participation capability metadata.
773    #[must_use]
774    pub const fn commit(&self) -> StoreCommitParticipation {
775        self.commit
776    }
777
778    /// Return recovery capability metadata.
779    #[must_use]
780    pub const fn recovery(&self) -> StoreRecoveryCapability {
781        self.recovery
782    }
783
784    /// Return schema-metadata persistence capability metadata.
785    #[must_use]
786    pub const fn schema_metadata(&self) -> StoreSchemaMetadataCapability {
787        self.schema_metadata
788    }
789
790    /// Return stable-memory manager ID, when generated wiring supplied it.
791    #[must_use]
792    pub const fn memory_id(&self) -> Option<u8> {
793        self.memory_id
794    }
795
796    /// Return durable stable-memory key, when generated wiring supplied it.
797    #[must_use]
798    pub const fn stable_key(&self) -> Option<&str> {
799        match &self.stable_key {
800            Some(value) => Some(value.as_str()),
801            None => None,
802        }
803    }
804
805    /// Return accepted schema/catalog version, when known.
806    #[must_use]
807    pub const fn schema_version(&self) -> Option<u32> {
808        self.schema_version
809    }
810
811    /// Return accepted schema/catalog fingerprint, when known.
812    #[must_use]
813    pub const fn schema_fingerprint(&self) -> Option<&str> {
814        match &self.schema_fingerprint {
815            Some(value) => Some(value.as_str()),
816            None => None,
817        }
818    }
819
820    /// Return total entry count.
821    #[must_use]
822    pub const fn entries(&self) -> u64 {
823        self.entries
824    }
825
826    /// Return user-namespace entry count.
827    #[must_use]
828    pub const fn user_entries(&self) -> u64 {
829        self.user_entries
830    }
831
832    /// Return system-namespace entry count.
833    #[must_use]
834    pub const fn system_entries(&self) -> u64 {
835        self.system_entries
836    }
837
838    /// Return memory usage in bytes.
839    #[must_use]
840    pub const fn memory_bytes(&self) -> u64 {
841        self.memory_bytes
842    }
843
844    /// Return the current explicit runtime lifecycle state for this index
845    /// store snapshot.
846    #[must_use]
847    pub const fn state(&self) -> IndexState {
848        self.state
849    }
850}
851
852#[cfg_attr(doc, doc = "EntitySnapshot\n\nPer-entity storage snapshot row.")]
853#[derive(CandidType, Clone, Debug, Default, Deserialize)]
854pub struct EntitySnapshot {
855    pub(crate) store: String,
856
857    pub(crate) path: String,
858
859    pub(crate) entries: u64,
860
861    pub(crate) memory_bytes: u64,
862}
863
864impl EntitySnapshot {
865    /// Construct one entity-storage snapshot row.
866    #[must_use]
867    pub(crate) const fn new(store: String, path: String, entries: u64, memory_bytes: u64) -> Self {
868        Self {
869            store,
870            path,
871            entries,
872            memory_bytes,
873        }
874    }
875
876    /// Borrow store path.
877    #[must_use]
878    pub const fn store(&self) -> &str {
879        self.store.as_str()
880    }
881
882    /// Borrow entity path.
883    #[must_use]
884    pub const fn path(&self) -> &str {
885        self.path.as_str()
886    }
887
888    /// Return row count.
889    #[must_use]
890    pub const fn entries(&self) -> u64 {
891        self.entries
892    }
893
894    /// Return memory usage in bytes.
895    #[must_use]
896    pub const fn memory_bytes(&self) -> u64 {
897        self.memory_bytes
898    }
899}