Skip to main content

nodedb_array/types/
array_id.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Stable array identifier — tenant- and database-scoped logical name.
4
5use serde::{Deserialize, Serialize};
6
7use nodedb_types::{DatabaseId, TenantId};
8
9fn default_database_id() -> DatabaseId {
10    DatabaseId::DEFAULT
11}
12
13/// Logical handle to an array within a tenant and database. The tuple
14/// `(tenant_id, database_id, name)` is the canonical storage/catalog key;
15/// `name` remains the user-visible identifier.
16#[derive(
17    Debug,
18    Clone,
19    PartialEq,
20    Eq,
21    Hash,
22    Serialize,
23    Deserialize,
24    zerompk::ToMessagePack,
25    zerompk::FromMessagePack,
26)]
27pub struct ArrayId {
28    pub tenant_id: TenantId,
29    /// Database scope. Missing fields in legacy persisted descriptors decode
30    /// as the built-in default database.
31    #[serde(default = "default_database_id")]
32    pub database_id: DatabaseId,
33    pub name: String,
34}
35
36impl ArrayId {
37    /// Construct a legacy/default-database identifier.
38    pub fn new(tenant_id: TenantId, name: impl Into<String>) -> Self {
39        Self::in_database(tenant_id, DatabaseId::DEFAULT, name)
40    }
41
42    /// Construct an identifier in an explicit database scope.
43    pub fn in_database(
44        tenant_id: TenantId,
45        database_id: DatabaseId,
46        name: impl Into<String>,
47    ) -> Self {
48        Self {
49            tenant_id,
50            database_id,
51            name: name.into(),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn array_id_round_trip_eq() {
62        let a = ArrayId::new(TenantId::new(1), "genome");
63        let b = ArrayId::new(TenantId::new(1), "genome");
64        assert_eq!(a, b);
65        assert_ne!(
66            a,
67            ArrayId::in_database(TenantId::new(1), DatabaseId::new(7), "genome")
68        );
69    }
70}