1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
5pub struct Id26([u8; 26]);
6
7impl Id26 {
8 pub fn from_str(s: &str) -> Option<Self> {
10 let b = s.as_bytes();
11 if b.len() != 26
12 || !b
13 .iter()
14 .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit())
15 {
16 return None;
17 }
18 let mut arr = [0u8; 26];
19 arr.copy_from_slice(b);
20 Some(Self(arr))
21 }
22
23 pub fn as_str(&self) -> &str {
25 unsafe { std::str::from_utf8_unchecked(&self.0) }
27 }
28
29 pub fn as_bytes(&self) -> &[u8; 26] {
30 &self.0
31 }
32
33 pub fn hash_u64(&self) -> u64 {
35 let mut h: u64 = 0xcbf2_9ce4_8422_2325;
36 for &b in &self.0 {
37 h ^= b as u64;
38 h = h.wrapping_mul(0x0000_0100_0000_01b3);
39 }
40 h
41 }
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
46pub struct ChannelId(pub Id26);
47
48impl ChannelId {
49 pub fn from_str(s: &str) -> Option<Self> {
50 Id26::from_str(s).map(Self)
51 }
52
53 pub fn as_str(&self) -> &str {
54 self.0.as_str()
55 }
56
57 pub fn as_bytes(&self) -> &[u8; 26] {
58 self.0.as_bytes()
59 }
60
61 pub fn hash_u64(&self) -> u64 {
62 self.0.hash_u64()
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
68pub struct ServerId(pub Id26);
69
70impl ServerId {
71 pub fn from_str(s: &str) -> Option<Self> {
72 Id26::from_str(s).map(Self)
73 }
74
75 pub fn as_str(&self) -> &str {
76 self.0.as_str()
77 }
78}
79
80pub fn is_canonical_post_id(s: &str) -> bool {
82 matches!(s.len(), 24 | 26)
83 && s.as_bytes()
84 .iter()
85 .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit())
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Hash)]
90pub struct TemporaryId(pub String);
91
92impl TemporaryId {
93 pub(crate) fn mint(now_ms: u64, sequence: u64) -> Self {
98 Self(format!("helix_tmp_{now_ms:016x}_{sequence:016x}"))
99 }
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
104pub struct Seq(pub u64);
105
106impl Seq {
107 pub fn next(self) -> Self {
108 Self(self.0 + 1)
109 }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum SendStatus {
114 Local,
115 Sending,
116 Sent,
117 UnSend,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
122pub struct InflightSync(pub helix_core::Correlation);
123
124#[derive(Debug, Clone, Copy)]
126pub struct Cursor {
127 pub value: Seq,
128}
129
130impl Cursor {
131 pub fn new(value: Seq) -> Self {
132 Self { value }
133 }
134
135 pub fn try_advance(&mut self, next: Seq) -> bool {
136 if next > self.value {
137 self.value = next;
138 true
139 } else {
140 false
141 }
142 }
143
144 pub fn value(&self) -> Seq {
145 self.value
146 }
147}
148
149#[derive(Debug, Clone, Copy, PartialEq, Eq)]
150pub enum ConnState {
151 Disconnected,
152 Connecting,
153 Connected,
154 Closing,
155}