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