Skip to main content

icydb_schema/node/
index.rs

1use crate::prelude::*;
2use std::{
3    fmt::{self, Display},
4    ops::Not,
5};
6
7///
8/// Index
9///
10
11#[derive(Clone, Debug, Serialize)]
12pub struct Index {
13    fields: &'static [&'static str],
14
15    #[serde(default, skip_serializing_if = "Not::not")]
16    unique: bool,
17}
18
19impl Index {
20    /// Build one index declaration from field-list and uniqueness metadata.
21    #[must_use]
22    pub const fn new(fields: &'static [&'static str], unique: bool) -> Self {
23        Self { fields, unique }
24    }
25
26    /// Borrow index field sequence.
27    #[must_use]
28    pub const fn fields(&self) -> &'static [&'static str] {
29        self.fields
30    }
31
32    /// Return whether the index enforces uniqueness.
33    #[must_use]
34    pub const fn is_unique(&self) -> bool {
35        self.unique
36    }
37
38    #[must_use]
39    pub fn is_prefix_of(&self, other: &Self) -> bool {
40        self.fields().len() < other.fields().len() && other.fields().starts_with(self.fields())
41    }
42}
43
44impl Display for Index {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        let fields = self.fields().join(", ");
47
48        if self.is_unique() {
49            write!(f, "UNIQUE ({fields})")
50        } else {
51            write!(f, "({fields})")
52        }
53    }
54}
55
56impl MacroNode for Index {
57    fn as_any(&self) -> &dyn std::any::Any {
58        self
59    }
60}
61
62impl ValidateNode for Index {}
63
64impl VisitableNode for Index {
65    fn route_key(&self) -> String {
66        self.fields().join(", ")
67    }
68}