1#[allow(clippy::len_without_is_empty)]
56pub trait Len {
57 fn len(&self) -> usize;
58}
59
60
61impl<T : Len + ?Sized> Len for Box<T> {
62 fn len(&self) -> usize {
63 (**self).len()
64 }
65}
66
67impl<T : Len + ?Sized> Len for std::rc::Rc<T> {
68 fn len(&self) -> usize {
69 (**self).len()
70 }
71}
72
73
74#[cfg(feature = "implement-Len-for-built_ins")]
75mod impl_for_built_ins {
76
77 mod isolate_ {
78 #![allow(non_snake_case)]
79
80
81 #[inline]
82 pub(super) fn get_len_str_(s : &str) -> usize {
83 s.len()
84 }
85
86 #[inline]
87 pub(super) fn get_len_Slice_<T>(s : &[T]) -> usize {
88 s.len()
89 }
90 }
91
92
93 impl super::Len for str {
96 fn len(&self) -> usize {
97 isolate_::get_len_str_(self)
98 }
99 }
100
101 impl super::Len for &str {
102 fn len(&self) -> usize {
103 isolate_::get_len_str_(self)
104 }
105 }
106
107 impl<T, const N: usize> super::Len for [T; N] {
110 fn len(&self) -> usize {
111 N
112 }
113 }
114
115 impl<T, const N: usize> super::Len for &[T; N] {
116 fn len(&self) -> usize {
117 N
118 }
119 }
120
121 impl<T> super::Len for [T] {
124 fn len(&self) -> usize {
125 isolate_::get_len_Slice_(self)
126 }
127 }
128
129 impl<T> super::Len for &[T] {
130 fn len(&self) -> usize {
131 isolate_::get_len_Slice_(self)
132 }
133 }
134}
135
136
137#[cfg(feature = "implement-Len-for-standard_collection_types")]
138mod impl_for_std_coll_types {
139 use std::collections as std_collections;
140
141
142 mod isolate_ {
143 #![allow(non_snake_case)]
144
145 use std::collections as std_collections;
146
147
148 #[inline]
149 pub(super) fn get_len_BTreeMap_<K, V>(coll : &std_collections::BTreeMap<K, V>) -> usize {
150 coll.len()
151 }
152
153 #[inline]
154 pub(super) fn get_len_BTreeSet_<T>(coll : &std_collections::BTreeSet<T>) -> usize {
155 coll.len()
156 }
157
158 #[inline]
159 pub(super) fn get_len_BinaryHeap_<T>(coll : &std_collections::BinaryHeap<T>) -> usize {
160 coll.len()
161 }
162
163 #[inline]
164 pub(super) fn get_len_HashMap_<K, V>(coll : &std_collections::HashMap<K, V>) -> usize {
165 coll.len()
166 }
167
168 #[inline]
169 pub(super) fn get_len_HashSet_<T>(coll : &std_collections::HashSet<T>) -> usize {
170 coll.len()
171 }
172
173 #[inline]
174 pub(super) fn get_len_LinkedList_<T>(coll : &std_collections::LinkedList<T>) -> usize {
175 coll.len()
176 }
177
178 #[inline]
180 pub(super) fn get_len_String_(s : &str) -> usize {
181 s.len()
182 }
183
184 #[inline]
185 pub(super) fn get_len_Vec_<T>(coll : &[T]) -> usize {
186 coll.len()
187 }
188
189 #[inline]
190 pub(super) fn get_len_VecDeque_<T>(coll : &std_collections::VecDeque<T>) -> usize {
191 coll.len()
192 }
193 }
194
195
196 impl<K, V> super::Len for std_collections::BTreeMap<K, V> {
199 fn len(&self) -> usize {
200 isolate_::get_len_BTreeMap_(self)
201 }
202 }
203
204 impl<T> super::Len for std_collections::BTreeSet<T> {
207 fn len(&self) -> usize {
208 isolate_::get_len_BTreeSet_(self)
209 }
210 }
211
212 impl<T> super::Len for std_collections::BinaryHeap<T> {
215 fn len(&self) -> usize {
216 isolate_::get_len_BinaryHeap_(self)
217 }
218 }
219
220 impl<K, V> super::Len for std_collections::HashMap<K, V> {
223 fn len(&self) -> usize {
224 isolate_::get_len_HashMap_(self)
225 }
226 }
227
228 impl<T> super::Len for std_collections::HashSet<T> {
231 fn len(&self) -> usize {
232 isolate_::get_len_HashSet_(self)
233 }
234 }
235
236 impl<T> super::Len for std_collections::LinkedList<T> {
239 fn len(&self) -> usize {
240 isolate_::get_len_LinkedList_(self)
241 }
242 }
243
244 impl super::Len for String {
247 fn len(&self) -> usize {
248 isolate_::get_len_String_(self)
249 }
250 }
251
252 impl<T> super::Len for Vec<T> {
255 fn len(&self) -> usize {
256 isolate_::get_len_Vec_(self)
257 }
258 }
259
260 impl<T> super::Len for std_collections::VecDeque<T> {
263 fn len(&self) -> usize {
264 isolate_::get_len_VecDeque_(self)
265 }
266 }
267}
268
269
270#[cfg(feature = "implement-Len-for-standard_ffi_types")]
271mod impl_for_std_ffi_types {
272 #![allow(non_snake_case)]
273
274 use std::ffi as std_ffi;
275
276
277 mod isolate_ {
278 #![allow(non_snake_case)]
279
280 use std::ffi as std_ffi;
281
282
283 #[inline]
284 pub(super) fn get_len_CStr_(cstr : &std_ffi::CStr) -> usize {
285 cstr.count_bytes()
286 }
287
288 #[inline]
289 pub(super) fn get_len_CString_(cstring : &std_ffi::CString) -> usize {
290 cstring.count_bytes()
291 }
292 }
293
294
295 impl super::Len for std_ffi::CStr {
298 fn len(&self) -> usize {
299 isolate_::get_len_CStr_(self)
300 }
301 }
302
303 impl super::Len for &std_ffi::CStr {
304 fn len(&self) -> usize {
305 isolate_::get_len_CStr_(self)
306 }
307 }
308
309 impl super::Len for std_ffi::CString {
312 fn len(&self) -> usize {
313 isolate_::get_len_CString_(self)
314 }
315 }
316}
317
318
319#[cfg(feature = "implement-Len-for-standard_path_types")]
320mod impl_for_std_path_types {
321 use std::path as std_path;
322
323
324 impl super::Len for &std_path::Path {
327 fn len(&self) -> usize {
328 self.as_os_str().len()
329 }
330 }
331
332 impl super::Len for std_path::PathBuf {
335 fn len(&self) -> usize {
336 self.as_os_str().len()
337 }
338 }
339
340 impl super::Len for &std_path::PathBuf {
341 fn len(&self) -> usize {
342 self.as_os_str().len()
343 }
344 }
345}
346
347
348#[cfg(feature = "implement-Len-for-standard_process_types")]
349mod impl_for_std_process_types {
350 #![allow(non_snake_case)]
351
352 use std::process as std_process;
353
354
355 mod isolate_ {
356 #![allow(non_snake_case)]
357
358 use std::process as std_process;
359
360
361 #[inline]
362 pub(super) fn get_len_CommandArgs_<'a>(ca : &std_process::CommandArgs<'a>) -> usize {
363 ca.len()
364 }
365
366 #[inline]
367 pub(super) fn get_len_CommandEnvs_<'a>(ce : &std_process::CommandEnvs<'a>) -> usize {
368 ce.len()
369 }
370 }
371
372
373 impl<'a> super::Len for &std_process::CommandArgs<'a> {
376 fn len(&self) -> usize {
377 isolate_::get_len_CommandArgs_(self)
378 }
379 }
380
381 impl<'a> super::Len for &std_process::CommandEnvs<'a> {
384 fn len(&self) -> usize {
385 isolate_::get_len_CommandEnvs_(self)
386 }
387 }
388}
389
390
391#[cfg(test)]
392mod tests {
393 #![allow(non_snake_case)]
394
395 use super::Len;
396
397 #[cfg(feature = "implement-Len-for-standard_collection_types")]
398 use std::rc::Rc;
399
400
401 #[allow(unused)]
402 fn as_Len<T : Len>(t : &T) -> &impl Len {
403 t
404 }
405
406
407 mod TEST_CUSTOM_TYPE {
408 #![allow(non_snake_case)]
409
410 use super::*;
411
412
413 #[derive(Debug)]
414 struct CustomType {
415 num_elements : usize,
416 }
417
418 impl Len for CustomType {
419 fn len(&self) -> usize {
420 self.num_elements
421 }
422 }
423
424
425 #[test]
426 fn TEST_WHEN_ZERO_ELEMENTS() {
427 let ct = CustomType { num_elements : 0 };
428
429 assert_eq!(0, ct.len());
430
431 let ct = &ct;
432
433 assert_eq!(0, ct.len());
434 }
435
436 #[test]
437 fn TEST_WHEN_HAVE_ELEMENTS() {
438 let ct = CustomType { num_elements : 1 };
439
440 assert_ne!(0, ct.len());
441
442 let ct = &ct;
443
444 assert_ne!(0, ct.len());
445 }
446 }
447
448
449 #[cfg(feature = "implement-Len-for-built_ins")]
450 mod TEST_BUILTIN_TYPES {
451 #![allow(non_snake_case)]
452
453 use super::*;
454
455
456 mod TEST_str {
457 #![allow(non_snake_case)]
458
459 use super::*;
460
461
462 #[test]
463 fn TEST_EMPTY() {
464 let s = "";
465
466 assert_eq!(0, s.len());
467
468 let ie = as_Len(&s);
469
470 assert_eq!(0, ie.len());
471 }
472
473 #[test]
474 fn TEST_NONEMPTY() {
475 let s = "abc";
476
477 assert_ne!(0, s.len());
478
479 let ie = as_Len(&s);
480
481 assert_ne!(0, ie.len());
482 }
483 }
484
485
486 mod TEST_Array {
487 #![allow(non_snake_case)]
488
489 use super::*;
490
491
492 #[test]
493 fn TEST_EMPTY() {
494 let ar : [i64; 0] = [];
495
496 assert_eq!(0, ar.len());
497
498 let ie = as_Len(&ar);
499
500 assert_eq!(0, ie.len());
501 }
502
503 #[test]
504 fn TEST_NONEMPTY() {
505 let ar : [i64; 1] = [ 0 ];
506
507 assert_ne!(0, ar.len());
508
509 let ie = as_Len(&ar);
510
511 assert_ne!(0, ie.len());
512 }
513 }
514
515
516 mod TEST_Slice {
517 #![allow(non_snake_case)]
518
519 use super::*;
520
521
522 #[test]
523 fn TEST_EMPTY() {
524 let ar : &[i64; 0] = &[];
525
526 assert_eq!(0, ar.len());
527
528 let ie = as_Len(&ar);
529
530 assert_eq!(0, ie.len());
531 }
532
533 #[test]
534 fn TEST_NONEMPTY() {
535 let ar = &[0];
536
537 assert_ne!(0, ar.len());
538
539 let ie = as_Len(&ar);
540
541 assert_ne!(0, ie.len());
542 }
543 }
544 }
545
546
547 #[cfg(feature = "implement-Len-for-standard_collection_types")]
548 mod TEST_STANDARD_TYPES {
549 #![allow(non_snake_case)]
550
551 use super::*;
552
553 use std::collections::{
554 BTreeMap,
555 BTreeSet,
556 BinaryHeap,
557 HashMap,
558 HashSet,
559 LinkedList,
560 VecDeque,
561 };
562
563
564 mod TEST_BTreeMapTU {
565 #![allow(non_snake_case)]
566
567 use super::*;
568
569
570 #[test]
571 fn TEST_EMPTY() {
572 let v : BTreeMap<i32, i32> = Default::default();
573
574 assert_eq!(0, v.len());
575
576 let ie = as_Len(&v);
577
578 assert_eq!(0, ie.len());
579 }
580
581 #[test]
582 fn TEST_NONEMPTY() {
583 let v = BTreeMap::from_iter(vec![ (0, 0) ]);
584
585 assert_ne!(0, v.len());
586
587 let ie = as_Len(&v);
588
589 assert_ne!(0, ie.len());
590 }
591 }
592
593
594 mod TEST_BTreeSetT {
595 #![allow(non_snake_case)]
596
597 use super::*;
598
599
600 #[test]
601 fn TEST_EMPTY() {
602 let v : BTreeSet<i32> = Default::default();
603
604 assert_eq!(0, v.len());
605
606 let ie = as_Len(&v);
607
608 assert_eq!(0, ie.len());
609 }
610
611 #[test]
612 fn TEST_NONEMPTY() {
613 let v = BTreeSet::from_iter(vec![ 0 ]);
614
615 assert_ne!(0, v.len());
616
617 let ie = as_Len(&v);
618
619 assert_ne!(0, ie.len());
620 }
621 }
622
623
624 mod TEST_BinaryHeapT {
625 #![allow(non_snake_case)]
626
627 use super::*;
628
629
630 #[test]
631 fn TEST_EMPTY() {
632 let v : BinaryHeap<i32> = Default::default();
633
634 assert_eq!(0, v.len());
635
636 let ie = as_Len(&v);
637
638 assert_eq!(0, ie.len());
639 }
640
641 #[test]
642 fn TEST_NONEMPTY() {
643 let v = BinaryHeap::from_iter(vec![ 0 ]);
644
645 assert_ne!(0, v.len());
646
647 let ie = as_Len(&v);
648
649 assert_ne!(0, ie.len());
650 }
651 }
652
653
654 mod TEST_HashMapTU {
655 #![allow(non_snake_case)]
656
657 use super::*;
658
659
660 #[test]
661 fn TEST_EMPTY() {
662 let v : HashMap<i32, i32> = Default::default();
663
664 assert_eq!(0, v.len());
665
666 let ie = as_Len(&v);
667
668 assert_eq!(0, ie.len());
669 }
670
671 #[test]
672 fn TEST_NONEMPTY() {
673 let v = HashMap::from_iter(vec![ (0, 0) ]);
674
675 assert_ne!(0, v.len());
676
677 let ie = as_Len(&v);
678
679 assert_ne!(0, ie.len());
680 }
681 }
682
683
684 mod TEST_HashSetT {
685 #![allow(non_snake_case)]
686
687 use super::*;
688
689
690 #[test]
691 fn TEST_EMPTY() {
692 let v : HashSet<i32> = Default::default();
693
694 assert_eq!(0, v.len());
695
696 let ie = as_Len(&v);
697
698 assert_eq!(0, ie.len());
699 }
700
701 #[test]
702 fn TEST_NONEMPTY() {
703 let v = HashSet::from_iter(vec![ 0 ]);
704
705 assert_ne!(0, v.len());
706
707 let ie = as_Len(&v);
708
709 assert_ne!(0, ie.len());
710 }
711 }
712
713
714 mod TEST_LinkedListT {
715 #![allow(non_snake_case)]
716
717 use super::*;
718
719
720 #[test]
721 fn TEST_EMPTY() {
722 let v : LinkedList<i32> = Default::default();
723
724 assert_eq!(0, v.len());
725
726 let ie = as_Len(&v);
727
728 assert_eq!(0, ie.len());
729 }
730
731 #[test]
732 fn TEST_NONEMPTY() {
733 let v = LinkedList::from_iter(vec![ 0 ]);
734
735 assert_ne!(0, v.len());
736
737 let ie = as_Len(&v);
738
739 assert_ne!(0, ie.len());
740 }
741 }
742
743
744 mod TEST_String {
745 #![allow(non_snake_case)]
746
747 use super::*;
748
749
750 #[test]
751 fn TEST_EMPTY() {
752 let s : String = "".into();
753
754 assert_eq!(0, s.len());
755
756 let ie = as_Len(&s);
757
758 assert_eq!(0, ie.len());
759 }
760
761 #[test]
762 fn TEST_NONEMPTY() {
763 let s : String = "abc".into();
764
765 assert_ne!(0, s.len());
766
767 let ie = as_Len(&s);
768
769 assert_ne!(0, ie.len());
770 }
771 }
772
773
774 mod TEST_String_IN_Box {
775 #![allow(non_snake_case)]
776
777 use super::*;
778
779
780 #[test]
781 fn TEST_EMPTY() {
782 let s : Box<String> = Box::new("".into());
783
784 assert_eq!(0, s.len());
785
786 let ie = as_Len(&s);
787
788 assert_eq!(0, ie.len());
789 }
790
791 #[test]
792 fn TEST_NONEMPTY() {
793 let s : Box<String> = Box::new("abc".into());
794
795 assert_ne!(0, s.len());
796
797 let ie = as_Len(&s);
798
799 assert_ne!(0, ie.len());
800 }
801 }
802
803
804 mod TEST_String_IN_Rc {
805 #![allow(non_snake_case)]
806
807 use super::*;
808
809
810 #[test]
811 fn TEST_EMPTY() {
812 let s : Rc<String> = Rc::new("".into());
813
814 assert_eq!(0, s.len());
815
816 let ie = as_Len(&s);
817
818 assert_eq!(0, ie.len());
819 }
820
821 #[test]
822 fn TEST_NONEMPTY() {
823 let s : Rc<String> = Rc::new("abc".into());
824
825 assert_ne!(0, s.len());
826
827 let ie = as_Len(&s);
828
829 assert_ne!(0, ie.len());
830 }
831 }
832
833
834 mod TEST_VecT {
835 #![allow(non_snake_case)]
836
837 use super::*;
838
839
840 #[test]
841 fn TEST_EMPTY() {
842 let v : Vec<i32> = Default::default();
843
844 assert_eq!(0, v.len());
845
846 let ie = as_Len(&v);
847
848 assert_eq!(0, ie.len());
849 }
850
851 #[test]
852 fn TEST_NONEMPTY() {
853 let v : Vec<i32> = vec![ 0 ];
854
855 assert_ne!(0, v.len());
856
857 let ie = as_Len(&v);
858
859 assert_ne!(0, ie.len());
860 }
861 }
862
863
864 mod TEST_VecDequeT {
865 #![allow(non_snake_case)]
866
867 use super::*;
868
869
870 #[test]
871 fn TEST_EMPTY() {
872 let v : VecDeque<i32> = Default::default();
873
874 assert_eq!(0, v.len());
875
876 let ie = as_Len(&v);
877
878 assert_eq!(0, ie.len());
879 }
880
881 #[test]
882 fn TEST_NONEMPTY() {
883 let v = VecDeque::from_iter(vec![ 0 ]);
884
885 assert_ne!(0, v.len());
886
887 let ie = as_Len(&v);
888
889 assert_ne!(0, ie.len());
890 }
891 }
892 }
893
894
895 #[cfg(feature = "implement-Len-for-standard_ffi_types")]
896 mod TEST_FFI_TYPES {
897 #![allow(non_snake_case)]
898
899 use super::*;
900
901 use std::ffi::{
902 CStr,
903 CString,
904 };
905
906
907 mod TEST_CStr {
908 #![allow(non_snake_case)]
909
910 use super::*;
911
912
913 #[test]
914 fn TEST_EMPTY() {
915 let s : &CStr = &CString::new("").unwrap();
916
917 assert_eq!(0, s.len());
918
919 let ie = as_Len(&s);
920
921 assert_eq!(0, ie.len());
922 }
923
924 #[test]
925 fn TEST_NONEMPTY() {
926 let s : &CStr = &CString::new("abc").unwrap();
927
928 assert_ne!(0, s.len());
929
930 let ie = as_Len(&s);
931
932 assert_ne!(0, ie.len());
933 }
934 }
935
936
937 mod TEST_CString {
938 #![allow(non_snake_case)]
939
940 use super::*;
941
942
943 #[test]
944 fn TEST_EMPTY() {
945 let s : CString = CString::new("").unwrap();
946
947 assert_eq!(0, s.len());
948
949 let ie = as_Len(&s);
950
951 assert_eq!(0, ie.len());
952 }
953
954 #[test]
955 fn TEST_NONEMPTY() {
956 let s : CString = CString::new("abc").unwrap();
957
958 assert_ne!(0, s.len());
959
960 let ie = as_Len(&s);
961
962 assert_ne!(0, ie.len());
963 }
964 }
965 }
966
967
968 #[cfg(feature = "implement-Len-for-standard_path_types")]
969 mod TEST_PATH_TYPES {
970 #![allow(non_snake_case)]
971
972 use super::*;
973
974 use std::path::{
975 Path,
976 PathBuf,
977 };
978
979
980 mod TEST_Path {
981 #![allow(non_snake_case)]
982
983 use super::*;
984
985
986 #[test]
987 fn TEST_EMPTY() {
988 let p = Path::new("");
989
990 assert_eq!(0, p.len());
991
992 let ie = as_Len(&p);
993
994 assert_eq!(0, ie.len());
995 }
996
997 #[test]
998 fn TEST_NOTEMPTY() {
999 let p = Path::new("./foo/bar.txt");
1000
1001 assert_ne!(0, p.len());
1002
1003 let ie = as_Len(&p);
1004
1005 assert_ne!(0, ie.len());
1006 }
1007 }
1008
1009
1010 mod TEST_PathBuf {
1011 #![allow(non_snake_case)]
1012
1013 use super::*;
1014
1015
1016 #[test]
1017 fn TEST_EMPTY() {
1018 let p = PathBuf::new();
1019
1020 assert_eq!(0, p.len());
1021
1022 let ie = as_Len(&p);
1023
1024 assert_eq!(0, ie.len());
1025 }
1026
1027 #[test]
1028 fn TEST_NOTEMPTY() {
1029 let mut p = PathBuf::new();
1030
1031 p.push("./foo/bar.txt");
1032
1033 assert_ne!(0, p.len());
1034
1035 let ie = as_Len(&p);
1036
1037 assert_ne!(0, ie.len());
1038 }
1039 }
1040 }
1041
1042
1043 #[cfg(feature = "implement-Len-for-standard_process_types")]
1044 mod TEST_PROCESS_TYPES {
1045 #![allow(non_snake_case)]
1046
1047 }
1048}
1049
1050
1051