icydb_schema/node/
index.rs1use crate::prelude::*;
2use std::{
3 fmt::{self, Display},
4 ops::Not,
5};
6
7#[derive(Clone, Debug, Serialize)]
12pub struct Index {
13 pub store: &'static str,
14 pub fields: &'static [&'static str],
15
16 #[serde(default, skip_serializing_if = "Not::not")]
17 pub unique: bool,
18}
19
20impl Index {
21 #[must_use]
22 pub fn is_prefix_of(&self, other: &Self) -> bool {
23 self.fields.len() < other.fields.len() && other.fields.starts_with(self.fields)
24 }
25}
26
27impl Display for Index {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 let fields = self.fields.join(", ");
30
31 if self.unique {
32 write!(f, "UNIQUE {}({})", self.store, fields)
33 } else {
34 write!(f, "{}({})", self.store, fields)
35 }
36 }
37}
38
39impl MacroNode for Index {
40 fn as_any(&self) -> &dyn std::any::Any {
41 self
42 }
43}
44
45impl ValidateNode for Index {
46 fn validate(&self) -> Result<(), ErrorTree> {
47 let mut errs = ErrorTree::new();
48 let schema = schema_read();
49
50 match schema.cast_node::<Store>(self.store) {
52 Ok(store) if !matches!(store.ty, StoreType::Index) => {
53 err!(errs, "store is not type Index");
54 }
55 Ok(_) => {}
56 Err(e) => errs.add(e),
57 }
58
59 errs.result()
60 }
61}
62
63impl VisitableNode for Index {
64 fn route_key(&self) -> String {
65 self.fields.join(", ")
66 }
67}