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