cdk_common/pub_sub/
index.rs1use std::fmt::Debug;
4use std::ops::Deref;
5use std::sync::atomic::{AtomicUsize, Ordering};
6
7use super::SubId;
8
9pub trait Indexable {
11 type Type: PartialOrd + Ord + Send + Sync + Debug;
14
15 fn to_indexes(&self) -> Vec<Index<Self::Type>>;
17}
18
19#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Clone)]
20pub struct Index<T>
27where
28 T: PartialOrd + Ord + Send + Sync + Debug,
29{
30 prefix: T,
31 counter: SubscriptionGlobalId,
32 id: super::SubId,
33}
34
35impl<T> From<&Index<T>> for super::SubId
36where
37 T: PartialOrd + Ord + Send + Sync + Debug,
38{
39 fn from(val: &Index<T>) -> Self {
40 val.id.clone()
41 }
42}
43
44impl<T> Deref for Index<T>
45where
46 T: PartialOrd + Ord + Send + Sync + Debug,
47{
48 type Target = T;
49
50 fn deref(&self) -> &Self::Target {
51 &self.prefix
52 }
53}
54
55impl<T> Index<T>
56where
57 T: PartialOrd + Ord + Send + Sync + Debug,
58{
59 pub fn cmp_prefix(&self, other: &Index<T>) -> std::cmp::Ordering {
61 self.prefix.cmp(&other.prefix)
62 }
63
64 pub fn unique_id(&self) -> usize {
66 self.counter.0
67 }
68}
69
70impl<T> From<(T, SubId, SubscriptionGlobalId)> for Index<T>
71where
72 T: PartialOrd + Ord + Send + Sync + Debug,
73{
74 fn from((prefix, id, counter): (T, SubId, SubscriptionGlobalId)) -> Self {
75 Self {
76 prefix,
77 id,
78 counter,
79 }
80 }
81}
82
83impl<T> From<(T, SubId)> for Index<T>
84where
85 T: PartialOrd + Ord + Send + Sync + Debug,
86{
87 fn from((prefix, id): (T, SubId)) -> Self {
88 Self {
89 prefix,
90 id,
91 counter: Default::default(),
92 }
93 }
94}
95
96impl<T> From<T> for Index<T>
97where
98 T: PartialOrd + Ord + Send + Sync + Debug,
99{
100 fn from(prefix: T) -> Self {
101 Self {
102 prefix,
103 id: Default::default(),
104 counter: SubscriptionGlobalId(0),
105 }
106 }
107}
108
109static COUNTER: AtomicUsize = AtomicUsize::new(0);
110
111#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
121pub struct SubscriptionGlobalId(usize);
122
123impl Default for SubscriptionGlobalId {
124 fn default() -> Self {
125 Self(COUNTER.fetch_add(1, Ordering::Relaxed))
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn test_index_from_tuple() {
135 let sub_id = SubId::from("test_sub_id");
136 let prefix = "test_prefix";
137 let index: Index<&str> = Index::from((prefix, sub_id.clone()));
138 assert_eq!(index.prefix, "test_prefix");
139 assert_eq!(index.id, sub_id);
140 }
141
142 #[test]
143 fn test_index_cmp_prefix() {
144 let sub_id = SubId::from("test_sub_id");
145 let index1: Index<&str> = Index::from(("a", sub_id.clone()));
146 let index2: Index<&str> = Index::from(("b", sub_id.clone()));
147 assert_eq!(index1.cmp_prefix(&index2), std::cmp::Ordering::Less);
148 }
149
150 #[test]
151 fn test_sub_id_from_str() {
152 let sub_id = SubId::from("test_sub_id");
153 assert_eq!(sub_id.0, "test_sub_id");
154 }
155
156 #[test]
157 fn test_sub_id_deref() {
158 let sub_id = SubId::from("test_sub_id");
159 assert_eq!(&*sub_id, "test_sub_id");
160 }
161}