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