Skip to main content

icydb_schema/node/
primary_key.rs

1use crate::prelude::*;
2
3///
4/// PrimaryKey
5///
6/// Structured primary-key metadata for an entity schema.
7///
8
9#[derive(Clone, Debug, Serialize)]
10pub struct PrimaryKey {
11    fields: &'static [&'static str],
12    source: PrimaryKeySource,
13}
14
15impl PrimaryKey {
16    /// Build one primary-key declaration from ordered field names and source.
17    #[must_use]
18    pub const fn new(fields: &'static [&'static str], source: PrimaryKeySource) -> Self {
19        Self { fields, source }
20    }
21
22    /// Borrow the ordered primary-key field names.
23    #[must_use]
24    pub const fn fields(&self) -> &'static [&'static str] {
25        self.fields
26    }
27
28    /// Borrow the scalar primary-key field name, if this primary-key
29    /// declaration is the one-component scalar case.
30    #[must_use]
31    pub const fn scalar_field(&self) -> Option<&'static str> {
32        if self.fields.len() == 1 {
33            Some(self.fields[0])
34        } else {
35            None
36        }
37    }
38
39    /// Borrow the primary-key source declaration.
40    #[must_use]
41    pub const fn source(&self) -> PrimaryKeySource {
42        self.source
43    }
44}
45
46///
47/// PrimaryKeySource
48///
49/// Declares where primary-key values originate.
50///
51
52#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)]
53pub enum PrimaryKeySource {
54    #[default]
55    Internal,
56
57    External,
58}
59
60#[cfg(test)]
61mod tests {
62    use super::{PrimaryKey, PrimaryKeySource};
63
64    #[test]
65    fn primary_key_keeps_ordered_field_list_without_scalarizing_composite_keys() {
66        let primary_key = PrimaryKey::new(&["tenant_id", "local_id"], PrimaryKeySource::External);
67
68        assert_eq!(primary_key.fields(), ["tenant_id", "local_id"]);
69        assert_eq!(primary_key.scalar_field(), None);
70        assert_eq!(primary_key.source(), PrimaryKeySource::External);
71    }
72
73    #[test]
74    fn scalar_primary_key_exposes_scalar_field() {
75        let primary_key = PrimaryKey::new(&["id"], PrimaryKeySource::Internal);
76
77        assert_eq!(primary_key.fields(), ["id"]);
78        assert_eq!(primary_key.scalar_field(), Some("id"));
79    }
80}