Skip to main content

frozen_collections_core/traits/
len.rs

1use alloc::collections::VecDeque;
2use alloc::rc::Rc;
3use alloc::sync::Arc;
4
5#[cfg(not(feature = "std"))]
6use {alloc::boxed::Box, alloc::string::String, alloc::vec::Vec};
7
8/// Types that can return a length.
9pub trait Len {
10    #[doc = include_str!("../doc_snippets/len.md")]
11    fn len(&self) -> usize;
12
13    #[doc = include_str!("../doc_snippets/is_empty.md")]
14    fn is_empty(&self) -> bool {
15        self.len() == 0
16    }
17}
18
19impl Len for String {
20    fn len(&self) -> usize {
21        self.len()
22    }
23}
24
25impl Len for str {
26    fn len(&self) -> usize {
27        self.len()
28    }
29}
30
31impl Len for &str {
32    fn len(&self) -> usize {
33        str::len(self)
34    }
35}
36
37impl Len for core::ffi::CStr {
38    fn len(&self) -> usize {
39        self.to_bytes().len()
40    }
41}
42
43impl<T> Len for [T] {
44    fn len(&self) -> usize {
45        self.len()
46    }
47}
48
49impl<T: ?Sized + Len> Len for Box<T> {
50    fn len(&self) -> usize {
51        T::len(self)
52    }
53}
54
55impl<T: ?Sized + Len> Len for Rc<T> {
56    fn len(&self) -> usize {
57        T::len(self)
58    }
59}
60
61impl<T: ?Sized + Len> Len for Arc<T> {
62    fn len(&self) -> usize {
63        T::len(self)
64    }
65}
66
67impl<T> Len for Vec<T> {
68    fn len(&self) -> usize {
69        self.len()
70    }
71}
72
73impl<T> Len for VecDeque<T> {
74    fn len(&self) -> usize {
75        self.len()
76    }
77}
78
79impl<K, V, BH> Len for hashbrown::HashMap<K, V, BH> {
80    fn len(&self) -> usize {
81        self.len()
82    }
83}
84
85impl<T, BH> Len for hashbrown::HashSet<T, BH> {
86    fn len(&self) -> usize {
87        self.len()
88    }
89}
90
91#[cfg(feature = "std")]
92impl<T, CM> Len for std::collections::HashSet<T, CM> {
93    fn len(&self) -> usize {
94        self.len()
95    }
96}
97
98#[cfg(feature = "std")]
99impl<K, V, CM> Len for std::collections::HashMap<K, V, CM> {
100    fn len(&self) -> usize {
101        self.len()
102    }
103}
104
105#[cfg(feature = "std")]
106impl Len for alloc::ffi::CString {
107    fn len(&self) -> usize {
108        self.as_bytes().len()
109    }
110}
111
112#[cfg(feature = "std")]
113impl<K, V> Len for alloc::collections::BTreeMap<K, V> {
114    fn len(&self) -> usize {
115        self.len()
116    }
117}
118
119#[cfg(feature = "std")]
120impl<T> Len for alloc::collections::BTreeSet<T> {
121    fn len(&self) -> usize {
122        self.len()
123    }
124}
125
126#[cfg(feature = "std")]
127impl<T> Len for alloc::collections::BinaryHeap<T> {
128    fn len(&self) -> usize {
129        self.len()
130    }
131}
132
133#[cfg(feature = "std")]
134impl<T> Len for alloc::collections::LinkedList<T> {
135    fn len(&self) -> usize {
136        self.len()
137    }
138}
139
140#[cfg(feature = "std")]
141impl Len for std::ffi::OsStr {
142    fn len(&self) -> usize {
143        self.len()
144    }
145}
146
147#[cfg(feature = "std")]
148impl Len for std::ffi::OsString {
149    fn len(&self) -> usize {
150        self.as_os_str().len()
151    }
152}
153
154#[cfg(test)]
155mod tests {
156    use crate::traits::Len;
157    use alloc::collections::VecDeque;
158    use alloc::rc::Rc;
159    use alloc::sync::Arc;
160    use alloc::vec;
161
162    fn get_len<T: Len + ?Sized>(value: &T) -> usize {
163        value.len()
164    }
165
166    #[test]
167    #[cfg(feature = "std")]
168    fn hashset_len_and_is_empty() {
169        let mut set = std::collections::HashSet::new();
170        assert_eq!(get_len(&set), 0);
171        assert!(set.is_empty());
172
173        _ = set.insert(1);
174        assert_eq!(get_len(&set), 1);
175        assert!(!set.is_empty());
176    }
177
178    #[test]
179    #[cfg(feature = "std")]
180    fn hashmap_len_and_is_empty() {
181        let mut map = std::collections::HashMap::new();
182        assert_eq!(get_len(&map), 0);
183        assert!(map.is_empty());
184
185        _ = map.insert("key", "value");
186        assert_eq!(get_len(&map), 1);
187        assert!(!map.is_empty());
188    }
189
190    #[test]
191    fn hashbrown_hashset_len_and_is_empty() {
192        let mut set = hashbrown::HashSet::new();
193        assert_eq!(get_len(&set), 0);
194        assert!(set.is_empty());
195
196        _ = set.insert(1);
197        assert_eq!(get_len(&set), 1);
198        assert!(!set.is_empty());
199    }
200
201    #[test]
202    fn hashbrown_hashmap_len_and_is_empty() {
203        let mut map = hashbrown::HashMap::new();
204        assert_eq!(get_len(&map), 0);
205        assert!(map.is_empty());
206
207        _ = map.insert("key", "value");
208        assert_eq!(get_len(&map), 1);
209        assert!(!map.is_empty());
210    }
211
212    #[test]
213    fn string_len_and_is_empty() {
214        let s = String::new();
215        assert_eq!(get_len(&s), 0);
216        assert!(s.is_empty());
217
218        let s = String::from("hello");
219        assert_eq!(get_len(&s), 5);
220        assert!(!s.is_empty());
221    }
222
223    #[test]
224    fn str_len_and_is_empty() {
225        let s = "";
226        assert_eq!(get_len(&s), 0);
227        assert!(s.is_empty());
228
229        let s = "hello";
230        assert_eq!(get_len(&s), 5);
231        assert!(!s.is_empty());
232    }
233
234    #[test]
235    #[cfg(feature = "std")]
236    fn cstring_len_and_is_empty() {
237        use alloc::ffi::CString;
238        let s = CString::new("").unwrap();
239        assert_eq!(get_len(&s), 0);
240        assert!(s.is_empty());
241
242        let s = CString::new("hello").unwrap();
243        assert_eq!(get_len(&s), 5);
244        assert!(!s.is_empty());
245    }
246
247    #[test]
248    #[cfg(feature = "std")]
249    fn cstr_len_and_is_empty() {
250        let s = c"";
251        assert_eq!(get_len(s), 0);
252        assert!(s.is_empty());
253
254        let s = c"hello";
255        assert_eq!(get_len(s), 5);
256        assert!(!s.is_empty());
257    }
258
259    #[test]
260    fn vec_len_and_is_empty() {
261        let v: Vec<i32> = Vec::new();
262        assert_eq!(get_len(&v), 0);
263        assert!(v.is_empty());
264
265        let v = vec![1, 2, 3];
266        assert_eq!(get_len(&v), 3);
267        assert!(!v.is_empty());
268    }
269
270    #[test]
271    fn vecdeque_len_and_is_empty() {
272        let v: VecDeque<i32> = VecDeque::new();
273        assert_eq!(get_len(&v), 0);
274        assert!(v.is_empty());
275
276        let v: VecDeque<i32> = alloc::vec![1, 2, 3].into();
277        assert_eq!(get_len(&v), 3);
278        assert!(!v.is_empty());
279    }
280
281    #[test]
282    fn box_len_and_is_empty() {
283        let b: Box<str> = Box::from("");
284        assert_eq!(get_len(&b), 0);
285        assert!(b.is_empty());
286
287        let b: Box<str> = Box::from("hello");
288        assert_eq!(get_len(&b), 5);
289        assert!(!b.is_empty());
290    }
291
292    #[test]
293    fn rc_len_and_is_empty() {
294        let r: Rc<str> = Rc::from("");
295        assert_eq!(get_len(&r), 0);
296        assert!(r.is_empty());
297
298        let r: Rc<str> = Rc::from("hello");
299        assert_eq!(get_len(&r), 5);
300        assert!(!r.is_empty());
301    }
302
303    #[test]
304    fn arc_len_and_is_empty() {
305        let a: Arc<str> = Arc::from("");
306        assert_eq!(get_len(&a), 0);
307        assert!(a.is_empty());
308
309        let a: Arc<str> = Arc::from("hello");
310        assert_eq!(get_len(&a), 5);
311        assert!(!a.is_empty());
312    }
313
314    #[test]
315    #[cfg(feature = "std")]
316    fn btreemap_len_and_is_empty() {
317        use alloc::collections::BTreeMap;
318        let mut map = BTreeMap::new();
319        assert_eq!(get_len(&map), 0);
320        assert!(map.is_empty());
321
322        _ = map.insert("key", "value");
323        assert_eq!(get_len(&map), 1);
324        assert!(!map.is_empty());
325    }
326
327    #[test]
328    #[cfg(feature = "std")]
329    fn btreeset_len_and_is_empty() {
330        use alloc::collections::BTreeSet;
331        let mut set = BTreeSet::new();
332        assert_eq!(get_len(&set), 0);
333        assert!(set.is_empty());
334
335        _ = set.insert(1);
336        assert_eq!(get_len(&set), 1);
337        assert!(!set.is_empty());
338    }
339
340    #[test]
341    #[cfg(feature = "std")]
342    fn binaryheap_len_and_is_empty() {
343        use alloc::collections::BinaryHeap;
344        let mut heap = BinaryHeap::new();
345        assert_eq!(get_len(&heap), 0);
346        assert!(heap.is_empty());
347
348        heap.push(1);
349        assert_eq!(get_len(&heap), 1);
350        assert!(!heap.is_empty());
351    }
352
353    #[test]
354    #[cfg(feature = "std")]
355    fn linkedlist_len_and_is_empty() {
356        use alloc::collections::LinkedList;
357        let mut list = LinkedList::new();
358        assert_eq!(get_len(&list), 0);
359        assert!(list.is_empty());
360
361        list.push_back(1);
362        assert_eq!(get_len(&list), 1);
363        assert!(!list.is_empty());
364    }
365
366    #[test]
367    #[cfg(feature = "std")]
368    fn osstr_len_and_is_empty() {
369        use std::ffi::OsStr;
370        let s = OsStr::new("");
371        assert_eq!(get_len(s), 0);
372        assert!(s.is_empty());
373
374        let s = OsStr::new("hello");
375        assert_eq!(get_len(s), 5);
376        assert!(!s.is_empty());
377    }
378
379    #[test]
380    #[cfg(feature = "std")]
381    fn osstring_len_and_is_empty() {
382        use std::ffi::OsString;
383        let s = OsString::new();
384        assert_eq!(get_len(&s), 0);
385        assert!(s.is_empty());
386
387        let s = OsString::from("hello");
388        assert_eq!(get_len(&s), 5);
389        assert!(!s.is_empty());
390    }
391
392    #[test]
393    fn slice_len_and_is_empty() {
394        let s: &[u8] = [].as_slice();
395        assert_eq!(get_len(s), 0);
396        assert!(s.is_empty());
397
398        let s = [0, 1, 2, 3, 4].as_slice();
399        assert_eq!(get_len(s), 5);
400        assert!(!s.is_empty());
401    }
402}