1use std::{
27 collections::{HashMap, HashSet},
28 fmt::{Debug, Display},
29 hash::Hash,
30};
31
32use indexmap::IndexMap;
33
34pub const FAILED: &str = "Condition failed";
40
41#[inline(always)]
47pub fn check_predicate_true(predicate: bool, fail_msg: &str) -> anyhow::Result<()> {
48 if !predicate {
49 anyhow::bail!("{fail_msg}")
50 }
51 Ok(())
52}
53
54#[inline(always)]
60pub fn check_predicate_false(predicate: bool, fail_msg: &str) -> anyhow::Result<()> {
61 if predicate {
62 anyhow::bail!("{fail_msg}")
63 }
64 Ok(())
65}
66
67#[inline(always)]
76pub fn check_nonempty_string<T: AsRef<str>>(s: T, param: &str) -> anyhow::Result<()> {
77 if s.as_ref().is_empty() {
78 anyhow::bail!("invalid string for '{param}', was empty");
79 }
80 Ok(())
81}
82
83#[inline(always)]
92pub fn check_valid_string<T: AsRef<str>>(s: T, param: &str) -> anyhow::Result<()> {
93 let s = s.as_ref();
94
95 if s.is_empty() {
96 anyhow::bail!("invalid string for '{param}', was empty");
97 }
98
99 let mut has_non_whitespace = false;
101 for c in s.chars() {
102 if !c.is_whitespace() {
103 has_non_whitespace = true;
104 }
105 if !c.is_ascii() {
106 anyhow::bail!("invalid string for '{param}' contained a non-ASCII char, was '{s}'");
107 }
108 }
109
110 if !has_non_whitespace {
111 anyhow::bail!("invalid string for '{param}', was all whitespace");
112 }
113
114 Ok(())
115}
116
117#[inline(always)]
126pub fn check_valid_string_optional<T: AsRef<str>>(s: Option<T>, param: &str) -> anyhow::Result<()> {
127 let s = s.as_ref();
128 if let Some(s) = s {
129 check_valid_string(s, param)?;
130 }
131 Ok(())
132}
133
134#[inline(always)]
140pub fn check_string_contains<T: AsRef<str>>(s: T, pat: &str, param: &str) -> anyhow::Result<()> {
141 let s = s.as_ref();
142 if !s.contains(pat) {
143 anyhow::bail!("invalid string for '{param}' did not contain '{pat}', was '{s}'")
144 }
145 Ok(())
146}
147
148#[inline(always)]
154pub fn check_equal<T: PartialEq + Debug + Display>(
155 lhs: T,
156 rhs: T,
157 lhs_param: &str,
158 rhs_param: &str,
159) -> anyhow::Result<()> {
160 if lhs != rhs {
161 anyhow::bail!("'{lhs_param}' value of {lhs} was not equal to '{rhs_param}' value of {rhs}");
162 }
163 Ok(())
164}
165
166#[inline(always)]
172pub fn check_equal_u8(lhs: u8, rhs: u8, lhs_param: &str, rhs_param: &str) -> anyhow::Result<()> {
173 if lhs != rhs {
174 anyhow::bail!("'{lhs_param}' u8 of {lhs} was not equal to '{rhs_param}' u8 of {rhs}")
175 }
176 Ok(())
177}
178
179#[inline(always)]
185pub fn check_equal_usize(
186 lhs: usize,
187 rhs: usize,
188 lhs_param: &str,
189 rhs_param: &str,
190) -> anyhow::Result<()> {
191 if lhs != rhs {
192 anyhow::bail!("'{lhs_param}' usize of {lhs} was not equal to '{rhs_param}' usize of {rhs}")
193 }
194 Ok(())
195}
196
197#[inline(always)]
203pub fn check_positive_u64(value: u64, param: &str) -> anyhow::Result<()> {
204 if value == 0 {
205 anyhow::bail!("invalid u64 for '{param}' not positive, was {value}")
206 }
207 Ok(())
208}
209
210#[inline(always)]
216pub fn check_positive_u128(value: u128, param: &str) -> anyhow::Result<()> {
217 if value == 0 {
218 anyhow::bail!("invalid u128 for '{param}' not positive, was {value}")
219 }
220 Ok(())
221}
222
223#[inline(always)]
229pub fn check_positive_i64(value: i64, param: &str) -> anyhow::Result<()> {
230 if value <= 0 {
231 anyhow::bail!("invalid i64 for '{param}' not positive, was {value}")
232 }
233 Ok(())
234}
235
236#[inline(always)]
242pub fn check_positive_i128(value: i128, param: &str) -> anyhow::Result<()> {
243 if value <= 0 {
244 anyhow::bail!("invalid i64 for '{param}' not positive, was {value}")
245 }
246 Ok(())
247}
248
249#[inline(always)]
255pub fn check_non_negative_f64(value: f64, param: &str) -> anyhow::Result<()> {
256 if value.is_nan() || value.is_infinite() {
257 anyhow::bail!("invalid f64 for '{param}', was {value}")
258 }
259 if value < 0.0 {
260 anyhow::bail!("invalid f64 for '{param}' negative, was {value}")
261 }
262 Ok(())
263}
264
265#[inline(always)]
271pub fn check_in_range_inclusive_u8(value: u8, l: u8, r: u8, param: &str) -> anyhow::Result<()> {
272 if value < l || value > r {
273 anyhow::bail!("invalid u8 for '{param}' not in range [{l}, {r}], was {value}")
274 }
275 Ok(())
276}
277
278#[inline(always)]
284pub fn check_in_range_inclusive_u64(value: u64, l: u64, r: u64, param: &str) -> anyhow::Result<()> {
285 if value < l || value > r {
286 anyhow::bail!("invalid u64 for '{param}' not in range [{l}, {r}], was {value}")
287 }
288 Ok(())
289}
290
291#[inline(always)]
297pub fn check_in_range_inclusive_i64(value: i64, l: i64, r: i64, param: &str) -> anyhow::Result<()> {
298 if value < l || value > r {
299 anyhow::bail!("invalid i64 for '{param}' not in range [{l}, {r}], was {value}")
300 }
301 Ok(())
302}
303
304#[inline(always)]
310pub fn check_in_range_inclusive_f64(value: f64, l: f64, r: f64, param: &str) -> anyhow::Result<()> {
311 const EPSILON: f64 = 1e-15; if value.is_nan() || value.is_infinite() {
314 anyhow::bail!("invalid f64 for '{param}', was {value}")
315 }
316 if value < l - EPSILON || value > r + EPSILON {
317 anyhow::bail!("invalid f64 for '{param}' not in range [{l}, {r}], was {value}")
318 }
319 Ok(())
320}
321
322#[inline(always)]
328pub fn check_in_range_inclusive_usize(
329 value: usize,
330 l: usize,
331 r: usize,
332 param: &str,
333) -> anyhow::Result<()> {
334 if value < l || value > r {
335 anyhow::bail!("invalid usize for '{param}' not in range [{l}, {r}], was {value}")
336 }
337 Ok(())
338}
339
340#[inline(always)]
346pub fn check_slice_empty<T>(slice: &[T], param: &str) -> anyhow::Result<()> {
347 if !slice.is_empty() {
348 anyhow::bail!(
349 "the '{param}' slice `&[{}]` was not empty",
350 std::any::type_name::<T>()
351 )
352 }
353 Ok(())
354}
355
356#[inline(always)]
362pub fn check_slice_not_empty<T>(slice: &[T], param: &str) -> anyhow::Result<()> {
363 if slice.is_empty() {
364 anyhow::bail!(
365 "the '{param}' slice `&[{}]` was empty",
366 std::any::type_name::<T>()
367 )
368 }
369 Ok(())
370}
371
372#[inline(always)]
378pub fn check_map_empty<K, V>(map: &HashMap<K, V>, param: &str) -> anyhow::Result<()> {
379 if !map.is_empty() {
380 anyhow::bail!(
381 "the '{param}' map `&<{}, {}>` was not empty",
382 std::any::type_name::<K>(),
383 std::any::type_name::<V>(),
384 )
385 }
386 Ok(())
387}
388
389#[inline(always)]
395pub fn check_map_not_empty<K, V>(map: &HashMap<K, V>, param: &str) -> anyhow::Result<()> {
396 if map.is_empty() {
397 anyhow::bail!(
398 "the '{param}' map `&<{}, {}>` was empty",
399 std::any::type_name::<K>(),
400 std::any::type_name::<V>(),
401 )
402 }
403 Ok(())
404}
405
406#[inline(always)]
412pub fn check_key_not_in_map<K, V>(
413 key: &K,
414 map: &HashMap<K, V>,
415 key_name: &str,
416 map_name: &str,
417) -> anyhow::Result<()>
418where
419 K: Hash + Eq + Display + Clone,
420 V: Debug,
421{
422 if map.contains_key(key) {
423 anyhow::bail!(
424 "the '{key_name}' key {key} was already in the '{map_name}' map `&<{}, {}>`",
425 std::any::type_name::<K>(),
426 std::any::type_name::<V>(),
427 )
428 }
429 Ok(())
430}
431
432#[inline(always)]
438pub fn check_key_in_map<K, V>(
439 key: &K,
440 map: &HashMap<K, V>,
441 key_name: &str,
442 map_name: &str,
443) -> anyhow::Result<()>
444where
445 K: Hash + Eq + Display + Clone,
446 V: Debug,
447{
448 if !map.contains_key(key) {
449 anyhow::bail!(
450 "the '{key_name}' key {key} was not in the '{map_name}' map `&<{}, {}>`",
451 std::any::type_name::<K>(),
452 std::any::type_name::<V>(),
453 )
454 }
455 Ok(())
456}
457
458#[inline(always)]
464pub fn check_key_not_in_index_map<K, V>(
465 key: &K,
466 map: &IndexMap<K, V>,
467 key_name: &str,
468 map_name: &str,
469) -> anyhow::Result<()>
470where
471 K: Hash + Eq + Display + Clone,
472 V: Debug,
473{
474 if map.contains_key(key) {
475 anyhow::bail!(
476 "the '{key_name}' key {key} was already in the '{map_name}' map `&<{}, {}>`",
477 std::any::type_name::<K>(),
478 std::any::type_name::<V>(),
479 )
480 }
481 Ok(())
482}
483
484#[inline(always)]
490pub fn check_key_in_index_map<K, V>(
491 key: &K,
492 map: &IndexMap<K, V>,
493 key_name: &str,
494 map_name: &str,
495) -> anyhow::Result<()>
496where
497 K: Hash + Eq + Display + Clone,
498 V: Debug,
499{
500 if !map.contains_key(key) {
501 anyhow::bail!(
502 "the '{key_name}' key {key} was not in the '{map_name}' map `&<{}, {}>`",
503 std::any::type_name::<K>(),
504 std::any::type_name::<V>(),
505 )
506 }
507 Ok(())
508}
509
510#[inline(always)]
516pub fn check_member_not_in_set<V>(
517 member: &V,
518 set: &HashSet<V>,
519 member_name: &str,
520 set_name: &str,
521) -> anyhow::Result<()>
522where
523 V: Hash + Eq + Display + Clone,
524{
525 if set.contains(member) {
526 anyhow::bail!(
527 "the '{member_name}' member was already in the '{set_name}' set `&<{}>`",
528 std::any::type_name::<V>(),
529 )
530 }
531 Ok(())
532}
533
534#[inline(always)]
540pub fn check_member_in_set<V>(
541 member: &V,
542 set: &HashSet<V>,
543 member_name: &str,
544 set_name: &str,
545) -> anyhow::Result<()>
546where
547 V: Hash + Eq + Display + Clone,
548{
549 if !set.contains(member) {
550 anyhow::bail!(
551 "the '{member_name}' member was not in the '{set_name}' set `&<{}>`",
552 std::any::type_name::<V>(),
553 )
554 }
555 Ok(())
556}
557
558#[cfg(test)]
562mod tests {
563 use std::fmt::Display;
564
565 use rstest::rstest;
566
567 use super::*;
568
569 #[rstest]
570 #[case(false, false)]
571 #[case(true, true)]
572 fn test_check_predicate_true(#[case] predicate: bool, #[case] expected: bool) {
573 let result = check_predicate_true(predicate, "the predicate was false").is_ok();
574 assert_eq!(result, expected);
575 }
576
577 #[rstest]
578 #[case(false, true)]
579 #[case(true, false)]
580 fn test_check_predicate_false(#[case] predicate: bool, #[case] expected: bool) {
581 let result = check_predicate_false(predicate, "the predicate was true").is_ok();
582 assert_eq!(result, expected);
583 }
584
585 #[rstest]
586 #[case("a")]
587 #[case(" ")] #[case(" ")] #[case("🦀")] #[case(" a")]
591 #[case("a ")]
592 #[case("abc")]
593 fn test_check_nonempty_string_with_valid_values(#[case] s: &str) {
594 assert!(check_nonempty_string(s, "value").is_ok());
595 }
596
597 #[rstest]
598 #[case("")] fn test_check_nonempty_string_with_invalid_values(#[case] s: &str) {
600 assert!(check_nonempty_string(s, "value").is_err());
601 }
602
603 #[rstest]
604 #[case(" a")]
605 #[case("a ")]
606 #[case("a a")]
607 #[case(" a ")]
608 #[case("abc")]
609 fn test_check_valid_string_with_valid_value(#[case] s: &str) {
610 assert!(check_valid_string(s, "value").is_ok());
611 }
612
613 #[rstest]
614 #[case("")] #[case(" ")] #[case(" ")] #[case("🦀")] fn test_check_valid_string_with_invalid_values(#[case] s: &str) {
619 assert!(check_valid_string(s, "value").is_err());
620 }
621
622 #[rstest]
623 #[case(None)]
624 #[case(Some(" a"))]
625 #[case(Some("a "))]
626 #[case(Some("a a"))]
627 #[case(Some(" a "))]
628 #[case(Some("abc"))]
629 fn test_check_valid_string_optional_with_valid_value(#[case] s: Option<&str>) {
630 assert!(check_valid_string_optional(s, "value").is_ok());
631 }
632
633 #[rstest]
634 #[case("a", "a")]
635 fn test_check_string_contains_when_does_contain(#[case] s: &str, #[case] pat: &str) {
636 assert!(check_string_contains(s, pat, "value").is_ok());
637 }
638
639 #[rstest]
640 #[case("a", "b")]
641 fn test_check_string_contains_when_does_not_contain(#[case] s: &str, #[case] pat: &str) {
642 assert!(check_string_contains(s, pat, "value").is_err());
643 }
644
645 #[rstest]
646 #[case(0u8, 0u8, "left", "right", true)]
647 #[case(1u8, 1u8, "left", "right", true)]
648 #[case(0u8, 1u8, "left", "right", false)]
649 #[case(1u8, 0u8, "left", "right", false)]
650 #[case(10i32, 10i32, "left", "right", true)]
651 #[case(10i32, 20i32, "left", "right", false)]
652 #[case("hello", "hello", "left", "right", true)]
653 #[case("hello", "world", "left", "right", false)]
654 fn test_check_equal<T: PartialEq + Debug + Display>(
655 #[case] lhs: T,
656 #[case] rhs: T,
657 #[case] lhs_param: &str,
658 #[case] rhs_param: &str,
659 #[case] expected: bool,
660 ) {
661 let result = check_equal(lhs, rhs, lhs_param, rhs_param).is_ok();
662 assert_eq!(result, expected);
663 }
664
665 #[rstest]
666 #[case(0, 0, "left", "right", true)]
667 #[case(1, 1, "left", "right", true)]
668 #[case(0, 1, "left", "right", false)]
669 #[case(1, 0, "left", "right", false)]
670 fn test_check_equal_u8_when_equal(
671 #[case] lhs: u8,
672 #[case] rhs: u8,
673 #[case] lhs_param: &str,
674 #[case] rhs_param: &str,
675 #[case] expected: bool,
676 ) {
677 let result = check_equal_u8(lhs, rhs, lhs_param, rhs_param).is_ok();
678 assert_eq!(result, expected);
679 }
680
681 #[rstest]
682 #[case(0, 0, "left", "right", true)]
683 #[case(1, 1, "left", "right", true)]
684 #[case(0, 1, "left", "right", false)]
685 #[case(1, 0, "left", "right", false)]
686 fn test_check_equal_usize_when_equal(
687 #[case] lhs: usize,
688 #[case] rhs: usize,
689 #[case] lhs_param: &str,
690 #[case] rhs_param: &str,
691 #[case] expected: bool,
692 ) {
693 let result = check_equal_usize(lhs, rhs, lhs_param, rhs_param).is_ok();
694 assert_eq!(result, expected);
695 }
696
697 #[rstest]
698 #[case(1, "value")]
699 fn test_check_positive_u64_when_positive(#[case] value: u64, #[case] param: &str) {
700 assert!(check_positive_u64(value, param).is_ok());
701 }
702
703 #[rstest]
704 #[case(0, "value")]
705 fn test_check_positive_u64_when_not_positive(#[case] value: u64, #[case] param: &str) {
706 assert!(check_positive_u64(value, param).is_err());
707 }
708
709 #[rstest]
710 #[case(1, "value")]
711 fn test_check_positive_i64_when_positive(#[case] value: i64, #[case] param: &str) {
712 assert!(check_positive_i64(value, param).is_ok());
713 }
714
715 #[rstest]
716 #[case(0, "value")]
717 #[case(-1, "value")]
718 fn test_check_positive_i64_when_not_positive(#[case] value: i64, #[case] param: &str) {
719 assert!(check_positive_i64(value, param).is_err());
720 }
721
722 #[rstest]
723 #[case(0.0, "value")]
724 #[case(1.0, "value")]
725 fn test_check_non_negative_f64_when_not_negative(#[case] value: f64, #[case] param: &str) {
726 assert!(check_non_negative_f64(value, param).is_ok());
727 }
728
729 #[rstest]
730 #[case(f64::NAN, "value")]
731 #[case(f64::INFINITY, "value")]
732 #[case(f64::NEG_INFINITY, "value")]
733 #[case(-0.1, "value")]
734 fn test_check_non_negative_f64_when_negative(#[case] value: f64, #[case] param: &str) {
735 assert!(check_non_negative_f64(value, param).is_err());
736 }
737
738 #[rstest]
739 #[case(0, 0, 0, "value")]
740 #[case(0, 0, 1, "value")]
741 #[case(1, 0, 1, "value")]
742 fn test_check_in_range_inclusive_u8_when_in_range(
743 #[case] value: u8,
744 #[case] l: u8,
745 #[case] r: u8,
746 #[case] desc: &str,
747 ) {
748 assert!(check_in_range_inclusive_u8(value, l, r, desc).is_ok());
749 }
750
751 #[rstest]
752 #[case(0, 1, 2, "value")]
753 #[case(3, 1, 2, "value")]
754 fn test_check_in_range_inclusive_u8_when_out_of_range(
755 #[case] value: u8,
756 #[case] l: u8,
757 #[case] r: u8,
758 #[case] param: &str,
759 ) {
760 assert!(check_in_range_inclusive_u8(value, l, r, param).is_err());
761 }
762
763 #[rstest]
764 #[case(0, 0, 0, "value")]
765 #[case(0, 0, 1, "value")]
766 #[case(1, 0, 1, "value")]
767 fn test_check_in_range_inclusive_u64_when_in_range(
768 #[case] value: u64,
769 #[case] l: u64,
770 #[case] r: u64,
771 #[case] param: &str,
772 ) {
773 assert!(check_in_range_inclusive_u64(value, l, r, param).is_ok());
774 }
775
776 #[rstest]
777 #[case(0, 1, 2, "value")]
778 #[case(3, 1, 2, "value")]
779 fn test_check_in_range_inclusive_u64_when_out_of_range(
780 #[case] value: u64,
781 #[case] l: u64,
782 #[case] r: u64,
783 #[case] param: &str,
784 ) {
785 assert!(check_in_range_inclusive_u64(value, l, r, param).is_err());
786 }
787
788 #[rstest]
789 #[case(0, 0, 0, "value")]
790 #[case(0, 0, 1, "value")]
791 #[case(1, 0, 1, "value")]
792 fn test_check_in_range_inclusive_i64_when_in_range(
793 #[case] value: i64,
794 #[case] l: i64,
795 #[case] r: i64,
796 #[case] param: &str,
797 ) {
798 assert!(check_in_range_inclusive_i64(value, l, r, param).is_ok());
799 }
800
801 #[rstest]
802 #[case(0.0, 0.0, 0.0, "value")]
803 #[case(0.0, 0.0, 1.0, "value")]
804 #[case(1.0, 0.0, 1.0, "value")]
805 fn test_check_in_range_inclusive_f64_when_in_range(
806 #[case] value: f64,
807 #[case] l: f64,
808 #[case] r: f64,
809 #[case] param: &str,
810 ) {
811 assert!(check_in_range_inclusive_f64(value, l, r, param).is_ok());
812 }
813
814 #[rstest]
815 #[case(-1e16, 0.0, 0.0, "value")]
816 #[case(1.0 + 1e16, 0.0, 1.0, "value")]
817 fn test_check_in_range_inclusive_f64_when_out_of_range(
818 #[case] value: f64,
819 #[case] l: f64,
820 #[case] r: f64,
821 #[case] param: &str,
822 ) {
823 assert!(check_in_range_inclusive_f64(value, l, r, param).is_err());
824 }
825
826 #[rstest]
827 #[case(0, 1, 2, "value")]
828 #[case(3, 1, 2, "value")]
829 fn test_check_in_range_inclusive_i64_when_out_of_range(
830 #[case] value: i64,
831 #[case] l: i64,
832 #[case] r: i64,
833 #[case] param: &str,
834 ) {
835 assert!(check_in_range_inclusive_i64(value, l, r, param).is_err());
836 }
837
838 #[rstest]
839 #[case(0, 0, 0, "value")]
840 #[case(0, 0, 1, "value")]
841 #[case(1, 0, 1, "value")]
842 fn test_check_in_range_inclusive_usize_when_in_range(
843 #[case] value: usize,
844 #[case] l: usize,
845 #[case] r: usize,
846 #[case] param: &str,
847 ) {
848 assert!(check_in_range_inclusive_usize(value, l, r, param).is_ok());
849 }
850
851 #[rstest]
852 #[case(0, 1, 2, "value")]
853 #[case(3, 1, 2, "value")]
854 fn test_check_in_range_inclusive_usize_when_out_of_range(
855 #[case] value: usize,
856 #[case] l: usize,
857 #[case] r: usize,
858 #[case] param: &str,
859 ) {
860 assert!(check_in_range_inclusive_usize(value, l, r, param).is_err());
861 }
862
863 #[rstest]
864 #[case(vec![], true)]
865 #[case(vec![1_u8], false)]
866 fn test_check_slice_empty(#[case] collection: Vec<u8>, #[case] expected: bool) {
867 let result = check_slice_empty(collection.as_slice(), "param").is_ok();
868 assert_eq!(result, expected);
869 }
870
871 #[rstest]
872 #[case(vec![], false)]
873 #[case(vec![1_u8], true)]
874 fn test_check_slice_not_empty(#[case] collection: Vec<u8>, #[case] expected: bool) {
875 let result = check_slice_not_empty(collection.as_slice(), "param").is_ok();
876 assert_eq!(result, expected);
877 }
878
879 #[rstest]
880 #[case(HashMap::new(), true)]
881 #[case(HashMap::from([("A".to_string(), 1_u8)]), false)]
882 fn test_check_map_empty(#[case] map: HashMap<String, u8>, #[case] expected: bool) {
883 let result = check_map_empty(&map, "param").is_ok();
884 assert_eq!(result, expected);
885 }
886
887 #[rstest]
888 #[case(HashMap::new(), false)]
889 #[case(HashMap::from([("A".to_string(), 1_u8)]), true)]
890 fn test_check_map_not_empty(#[case] map: HashMap<String, u8>, #[case] expected: bool) {
891 let result = check_map_not_empty(&map, "param").is_ok();
892 assert_eq!(result, expected);
893 }
894
895 #[rstest]
896 #[case(&HashMap::<u32, u32>::new(), 5, "key", "map", true)] #[case(&HashMap::from([(1, 10), (2, 20)]), 1, "key", "map", false)] #[case(&HashMap::from([(1, 10), (2, 20)]), 5, "key", "map", true)] fn test_check_key_not_in_map(
900 #[case] map: &HashMap<u32, u32>,
901 #[case] key: u32,
902 #[case] key_name: &str,
903 #[case] map_name: &str,
904 #[case] expected: bool,
905 ) {
906 let result = check_key_not_in_map(&key, map, key_name, map_name).is_ok();
907 assert_eq!(result, expected);
908 }
909
910 #[rstest]
911 #[case(&HashMap::<u32, u32>::new(), 5, "key", "map", false)] #[case(&HashMap::from([(1, 10), (2, 20)]), 1, "key", "map", true)] #[case(&HashMap::from([(1, 10), (2, 20)]), 5, "key", "map", false)] fn test_check_key_in_map(
915 #[case] map: &HashMap<u32, u32>,
916 #[case] key: u32,
917 #[case] key_name: &str,
918 #[case] map_name: &str,
919 #[case] expected: bool,
920 ) {
921 let result = check_key_in_map(&key, map, key_name, map_name).is_ok();
922 assert_eq!(result, expected);
923 }
924
925 #[rstest]
926 #[case(&IndexMap::<u32, u32>::new(), 5, "key", "map", true)] #[case(&IndexMap::from([(1, 10), (2, 20)]), 1, "key", "map", false)] #[case(&IndexMap::from([(1, 10), (2, 20)]), 5, "key", "map", true)] fn test_check_key_not_in_index_map(
930 #[case] map: &IndexMap<u32, u32>,
931 #[case] key: u32,
932 #[case] key_name: &str,
933 #[case] map_name: &str,
934 #[case] expected: bool,
935 ) {
936 let result = check_key_not_in_index_map(&key, map, key_name, map_name).is_ok();
937 assert_eq!(result, expected);
938 }
939
940 #[rstest]
941 #[case(&IndexMap::<u32, u32>::new(), 5, "key", "map", false)] #[case(&IndexMap::from([(1, 10), (2, 20)]), 1, "key", "map", true)] #[case(&IndexMap::from([(1, 10), (2, 20)]), 5, "key", "map", false)] fn test_check_key_in_index_map(
945 #[case] map: &IndexMap<u32, u32>,
946 #[case] key: u32,
947 #[case] key_name: &str,
948 #[case] map_name: &str,
949 #[case] expected: bool,
950 ) {
951 let result = check_key_in_index_map(&key, map, key_name, map_name).is_ok();
952 assert_eq!(result, expected);
953 }
954
955 #[rstest]
956 #[case(&HashSet::<u32>::new(), 5, "member", "set", true)] #[case(&HashSet::from([1, 2]), 1, "member", "set", false)] #[case(&HashSet::from([1, 2]), 5, "member", "set", true)] fn test_check_member_not_in_set(
960 #[case] set: &HashSet<u32>,
961 #[case] member: u32,
962 #[case] member_name: &str,
963 #[case] set_name: &str,
964 #[case] expected: bool,
965 ) {
966 let result = check_member_not_in_set(&member, set, member_name, set_name).is_ok();
967 assert_eq!(result, expected);
968 }
969
970 #[rstest]
971 #[case(&HashSet::<u32>::new(), 5, "member", "set", false)] #[case(&HashSet::from([1, 2]), 1, "member", "set", true)] #[case(&HashSet::from([1, 2]), 5, "member", "set", false)] fn test_check_member_in_set(
975 #[case] set: &HashSet<u32>,
976 #[case] member: u32,
977 #[case] member_name: &str,
978 #[case] set_name: &str,
979 #[case] expected: bool,
980 ) {
981 let result = check_member_in_set(&member, set, member_name, set_name).is_ok();
982 assert_eq!(result, expected);
983 }
984}