use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IndexDef {
pub id: u32,
pub name: String,
pub label: String,
pub property: String,
pub kind: IndexKind,
pub state: IndexState,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum IndexKind {
Ordered,
Text {
consistency: TextConsistency,
},
Structural {
dimensions: u32,
},
}
impl IndexKind {
#[must_use]
pub fn applied(self) -> bool {
matches!(self, Self::Text { .. } | Self::Structural { .. })
}
}
pub const TEXT_ALL_PROPERTIES: &str = "*";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum TextConsistency {
Immediate,
Eventual,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "state")]
pub enum IndexState {
Building {
cursor: u64,
},
Ready,
Dropping {
cursor: u64,
},
}
impl IndexState {
#[must_use]
pub fn covered(self) -> (u64, u64) {
match self {
Self::Building { cursor } => (0, cursor),
Self::Ready => (0, u64::MAX),
Self::Dropping { cursor } => (cursor, u64::MAX),
}
}
#[must_use]
pub fn covers(self, ord: u64) -> bool {
let (start, end) = self.covered();
start <= ord && ord < end
}
#[must_use]
pub fn label(self) -> &'static str {
match self {
Self::Building { .. } => "building",
Self::Ready => "ready",
Self::Dropping { .. } => "dropping",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn coverage_follows_the_cursor() {
assert!(!IndexState::Building { cursor: 0 }.covers(0));
let building = IndexState::Building { cursor: 5 };
assert!(building.covers(0) && building.covers(4) && !building.covers(5));
assert!(IndexState::Ready.covers(u64::MAX - 1));
let dropping = IndexState::Dropping { cursor: 5 };
assert!(!dropping.covers(4) && dropping.covers(5));
}
}