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