aabel_identifier_rs/
lib.rs1pub trait Identifier: Eq {}
19impl<T> Identifier for T where T: Eq {}
20
21pub trait PartialOrdIdentifier: Identifier + PartialOrd {}
25impl<T> PartialOrdIdentifier for T where T: Eq + PartialOrd {}
26
27pub trait IntoIdentifierIterator {
42 type Item: Identifier;
43
44 fn into_ids_iterator<F>(self, next: F) -> impl Iterator<Item = Self::Item>
45 where
46 F: Fn(&Self::Item) -> Self::Item;
47}
48
49struct IdentifierIterator<F, I>
53where
54 F: Fn(&I) -> I,
55 I: Copy,
56{
57 current_id: I,
58 get_next_id: F,
59}
60
61impl<F, I> Iterator for IdentifierIterator<F, I>
62where
63 F: Fn(&I) -> I,
64 I: Copy,
65{
66 type Item = I;
67
68 fn next(&mut self) -> Option<Self::Item> {
69 let nxt = self.current_id;
70 self.current_id = (self.get_next_id)(&self.current_id);
71 Some(nxt)
72 }
73}
74
75impl<T> IntoIdentifierIterator for T
76where
77 T: Copy + Identifier,
78{
79 type Item = Self;
80
81 fn into_ids_iterator<F>(self, next: F) -> impl Iterator<Item = Self::Item>
82 where
83 F: Fn(&Self::Item) -> Self::Item,
84 {
85 IdentifierIterator {
86 current_id: self,
87 get_next_id: next,
88 }
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 fn test_identifier(_id: impl Identifier) {
97 assert!(true);
98 }
99
100 fn test_partialord_identifier(_id: impl PartialOrdIdentifier) {
101 assert!(true);
102 }
103
104 #[test]
105 fn identifier_u8() {
106 let id = 10_u8;
107 test_identifier(id)
108 }
109
110 #[test]
111 fn identifier_u64() {
112 let id = 10_u64;
113 test_identifier(id)
114 }
115
116 #[test]
117 fn identifier_str() {
118 let id = "test";
119 test_identifier(id)
120 }
121
122 #[test]
123 fn identifier_arr() {
124 let id = [1, 2, 3];
125 test_identifier(id)
126 }
127
128 #[test]
129 fn identifier_vec() {
130 let id = vec![1, 2, 3];
131 test_identifier(id)
132 }
133
134 #[test]
135 fn identifier_eq() {
136 fn cmp_identifiers<I>(a: I, b: I) -> bool
137 where
138 I: Identifier,
139 {
140 a == b
141 }
142
143 assert!(cmp_identifiers(10_u16, 10_u16));
144 assert!(!cmp_identifiers(10_u16, 20_u16));
145 }
146
147 #[test]
148 fn partialord_identifier_u8() {
149 let id = 10_u8;
150 test_partialord_identifier(id)
151 }
152
153 #[test]
154 fn partialord_identifier_u64() {
155 let id = 10_u64;
156 test_partialord_identifier(id)
157 }
158
159 #[test]
160 fn partialord_identity_str() {
161 let id = "test";
162 test_partialord_identifier(id)
163 }
164
165 #[test]
166 fn partialord_identifier_arr() {
167 let id = [1, 2, 3];
168 test_partialord_identifier(id)
169 }
170
171 #[test]
172 fn partialord_identifier_vec() {
173 let id = vec![1, 2, 3];
174 test_partialord_identifier(id)
175 }
176
177 #[test]
178 fn partialord_idenitifier_cmp() {
179 fn cmp_identifiers<I>(a: I, b: &I) -> Option<std::cmp::Ordering>
180 where
181 I: PartialOrdIdentifier,
182 {
183 a.partial_cmp(b)
184 }
185
186 assert!(cmp_identifiers(10_u8, &10_u8).is_some());
187 assert!(cmp_identifiers("az", &"za").is_some());
188 }
189
190 #[test]
191 fn iter_u8() {
192 let id = 10_u8;
193 let mut iter = id.into_ids_iterator(|id| id + 1);
194 assert_eq!(iter.next(), Some(10));
195 assert_eq!(iter.next(), Some(11));
196 }
197
198 #[test]
199 fn iter_u64() {
200 let id = 10_u64;
201 let mut iter = id.into_ids_iterator(|id| id + 1);
202 assert_eq!(iter.next(), Some(10));
203 assert_eq!(iter.next(), Some(11));
204 }
205
206 #[test]
207 fn iter_str() {
208 let id = "a";
209 let mut iter = id.into_ids_iterator(|id| id);
210 assert_eq!(iter.next(), Some("a"));
211 assert_eq!(iter.next(), Some("a"));
212 }
213
214 #[test]
215 fn iter_string() {
216 let id = "a".to_string();
217 let mut iter = id.into_ids_iterator(|id| id);
218 assert_eq!(iter.next(), Some(&"a".into()));
219 assert_eq!(iter.next(), Some(&"a".into()));
220 }
221}