Skip to main content

escriba_core/
id.rs

1//! Opaque identifiers — one counter per domain. All are transparent newtypes
2//! so serde emits them as plain numbers.
3
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7macro_rules! id_type {
8    ($name:ident, $doc:literal) => {
9        #[doc = $doc]
10        #[derive(
11            Debug,
12            Clone,
13            Copy,
14            PartialEq,
15            Eq,
16            PartialOrd,
17            Ord,
18            Hash,
19            Default,
20            Serialize,
21            Deserialize,
22            JsonSchema,
23        )]
24        #[serde(transparent)]
25        pub struct $name(pub u64);
26
27        impl std::fmt::Display for $name {
28            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29                write!(f, "{}#{}", stringify!($name), self.0)
30            }
31        }
32    };
33}
34
35id_type!(
36    BufferId,
37    "Identifies one open buffer — unique across the editor session."
38);
39id_type!(
40    WindowId,
41    "Identifies one UI window (one viewport over a buffer)."
42);
43id_type!(
44    CaretId,
45    "Identifies a caret within a selection, stable across edits."
46);
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn ids_are_newtypes() {
54        let a = BufferId(1);
55        let b = BufferId(1);
56        assert_eq!(a, b);
57        let s = serde_json::to_string(&a).unwrap();
58        assert_eq!(s, "1");
59    }
60
61    #[test]
62    fn display_format() {
63        assert_eq!(BufferId(42).to_string(), "BufferId#42");
64    }
65}