Skip to main content

haystack_core/kinds/
singletons.rs

1// Haystack singleton types: Marker, NA, Remove
2
3/// Marker tag — boolean presence indicator.
4/// In Zinc: `M`. In JSON: `{"_kind": "marker"}`.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub struct Marker;
7
8/// Not Available — missing or invalid data sentinel.
9/// In Zinc: `NA`. In JSON: `{"_kind": "na"}`.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct NA;
12
13/// Remove — tag removal in diff/update operations.
14/// In Zinc: `R`. In JSON: `{"_kind": "remove"}`.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub struct Remove;
17
18impl std::fmt::Display for Marker {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        write!(f, "\u{2713}") // ✓
21    }
22}
23
24impl std::fmt::Display for NA {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        write!(f, "NA")
27    }
28}
29
30impl std::fmt::Display for Remove {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        write!(f, "remove")
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn marker_display() {
42        assert_eq!(Marker.to_string(), "\u{2713}");
43    }
44
45    #[test]
46    fn marker_equality() {
47        assert_eq!(Marker, Marker);
48    }
49
50    #[test]
51    fn na_display() {
52        assert_eq!(NA.to_string(), "NA");
53    }
54
55    #[test]
56    fn remove_display() {
57        assert_eq!(Remove.to_string(), "remove");
58    }
59
60    #[test]
61    fn singletons_are_copy() {
62        let m = Marker;
63        let m2 = m;
64        assert_eq!(m, m2);
65    }
66
67    #[test]
68    fn singletons_are_hashable() {
69        use std::collections::HashSet;
70        let mut set = HashSet::new();
71        set.insert(Marker);
72        assert!(set.contains(&Marker));
73    }
74}