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
41pub fn check_predicate_true(predicate: bool, fail_msg: &str) -> anyhow::Result<()> {
47 if !predicate {
48 anyhow::bail!("{fail_msg}")
49 }
50 Ok(())
51}
52
53pub fn check_predicate_false(predicate: bool, fail_msg: &str) -> anyhow::Result<()> {
59 if predicate {
60 anyhow::bail!("{fail_msg}")
61 }
62 Ok(())
63}
64
65pub fn check_nonempty_string<T: AsRef<str>>(s: T, param: &str) -> anyhow::Result<()> {
74 if s.as_ref().is_empty() {
75 anyhow::bail!("invalid string for '{param}', was empty");
76 }
77 Ok(())
78}
79
80pub fn check_valid_string<T: AsRef<str>>(s: T, param: &str) -> anyhow::Result<()> {
89 let s = s.as_ref();
90
91 if s.is_empty() {
92 anyhow::bail!("invalid string for '{param}', was empty");
93 }
94
95 let mut has_non_whitespace = false;
97 for c in s.chars() {
98 if !c.is_whitespace() {
99 has_non_whitespace = true;
100 }
101 if !c.is_ascii() {
102 anyhow::bail!("invalid string for '{param}' contained a non-ASCII char, was '{s}'");
103 }
104 }
105
106 if !has_non_whitespace {
107 anyhow::bail!("invalid string for '{param}', was all whitespace");
108 }
109
110 Ok(())
111}
112
113pub fn check_valid_string_optional<T: AsRef<str>>(s: Option<T>, param: &str) -> anyhow::Result<()> {
122 let s = s.as_ref();
123 if let Some(s) = s {
124 check_valid_string(s, param)?;
125 }
126 Ok(())
127}
128
129pub fn check_string_contains<T: AsRef<str>>(s: T, pat: &str, param: &str) -> anyhow::Result<()> {
135 let s = s.as_ref();
136 if !s.contains(pat) {
137 anyhow::bail!("invalid string for '{param}' did not contain '{pat}', was '{s}'")
138 }
139 Ok(())
140}
141
142pub fn check_equal<T: PartialEq + Debug + Display>(
148 lhs: T,
149 rhs: T,
150 lhs_param: &str,
151 rhs_param: &str,
152) -> anyhow::Result<()> {
153 if lhs != rhs {
154 anyhow::bail!("'{lhs_param}' value of {lhs} was not equal to '{rhs_param}' value of {rhs}",);
155 }
156 Ok(())
157}
158
159pub fn check_equal_u8(lhs: u8, rhs: u8, lhs_param: &str, rhs_param: &str) -> anyhow::Result<()> {
165 if lhs != rhs {
166 anyhow::bail!("'{lhs_param}' u8 of {lhs} was not equal to '{rhs_param}' u8 of {rhs}")
167 }
168 Ok(())
169}
170
171pub fn check_equal_usize(
177 lhs: usize,
178 rhs: usize,
179 lhs_param: &str,
180 rhs_param: &str,
181) -> anyhow::Result<()> {
182 if lhs != rhs {
183 anyhow::bail!("'{lhs_param}' usize of {lhs} was not equal to '{rhs_param}' usize of {rhs}")
184 }
185 Ok(())
186}
187
188pub fn check_positive_u64(value: u64, param: &str) -> anyhow::Result<()> {
194 if value == 0 {
195 anyhow::bail!("invalid u64 for '{param}' not positive, was {value}")
196 }
197 Ok(())
198}
199
200pub fn check_positive_u128(value: u128, param: &str) -> anyhow::Result<()> {
206 if value == 0 {
207 anyhow::bail!("invalid u128 for '{param}' not positive, was {value}")
208 }
209 Ok(())
210}
211
212pub fn check_positive_i64(value: i64, param: &str) -> anyhow::Result<()> {
218 if value <= 0 {
219 anyhow::bail!("invalid i64 for '{param}' not positive, was {value}")
220 }
221 Ok(())
222}
223
224pub fn check_positive_i128(value: i128, param: &str) -> anyhow::Result<()> {
230 if value <= 0 {
231 anyhow::bail!("invalid i64 for '{param}' not positive, was {value}")
232 }
233 Ok(())
234}
235
236pub fn check_non_negative_f64(value: f64, param: &str) -> anyhow::Result<()> {
242 if value.is_nan() || value.is_infinite() {
243 anyhow::bail!("invalid f64 for '{param}', was {value}")
244 }
245 if value < 0.0 {
246 anyhow::bail!("invalid f64 for '{param}' negative, was {value}")
247 }
248 Ok(())
249}
250
251pub fn check_in_range_inclusive_u8(value: u8, l: u8, r: u8, param: &str) -> anyhow::Result<()> {
257 if value < l || value > r {
258 anyhow::bail!("invalid u8 for '{param}' not in range [{l}, {r}], was {value}")
259 }
260 Ok(())
261}
262
263pub fn check_in_range_inclusive_u64(value: u64, l: u64, r: u64, param: &str) -> anyhow::Result<()> {
269 if value < l || value > r {
270 anyhow::bail!("invalid u64 for '{param}' not in range [{l}, {r}], was {value}")
271 }
272 Ok(())
273}
274
275pub fn check_in_range_inclusive_i64(value: i64, l: i64, r: i64, param: &str) -> anyhow::Result<()> {
281 if value < l || value > r {
282 anyhow::bail!("invalid i64 for '{param}' not in range [{l}, {r}], was {value}")
283 }
284 Ok(())
285}
286
287pub fn check_in_range_inclusive_f64(value: f64, l: f64, r: f64, param: &str) -> anyhow::Result<()> {
293 const EPSILON: f64 = 1e-15; if value.is_nan() || value.is_infinite() {
296 anyhow::bail!("invalid f64 for '{param}', was {value}")
297 }
298 if value < l - EPSILON || value > r + EPSILON {
299 anyhow::bail!("invalid f64 for '{param}' not in range [{l}, {r}], was {value}")
300 }
301 Ok(())
302}
303
304pub fn check_in_range_inclusive_usize(
310 value: usize,
311 l: usize,
312 r: usize,
313 param: &str,
314) -> anyhow::Result<()> {
315 if value < l || value > r {
316 anyhow::bail!("invalid usize for '{param}' not in range [{l}, {r}], was {value}")
317 }
318 Ok(())
319}
320
321pub fn check_slice_empty<T>(slice: &[T], param: &str) -> anyhow::Result<()> {
327 if !slice.is_empty() {
328 anyhow::bail!(
329 "the '{param}' slice `&[{}]` was not empty",
330 std::any::type_name::<T>()
331 )
332 }
333 Ok(())
334}
335
336pub fn check_slice_not_empty<T>(slice: &[T], param: &str) -> anyhow::Result<()> {
342 if slice.is_empty() {
343 anyhow::bail!(
344 "the '{param}' slice `&[{}]` was empty",
345 std::any::type_name::<T>()
346 )
347 }
348 Ok(())
349}
350
351pub fn check_map_empty<K, V>(map: &HashMap<K, V>, param: &str) -> anyhow::Result<()> {
357 if !map.is_empty() {
358 anyhow::bail!(
359 "the '{param}' map `&<{}, {}>` was not empty",
360 std::any::type_name::<K>(),
361 std::any::type_name::<V>(),
362 )
363 }
364 Ok(())
365}
366
367pub fn check_map_not_empty<K, V>(map: &HashMap<K, V>, param: &str) -> anyhow::Result<()> {
373 if map.is_empty() {
374 anyhow::bail!(
375 "the '{param}' map `&<{}, {}>` was empty",
376 std::any::type_name::<K>(),
377 std::any::type_name::<V>(),
378 )
379 }
380 Ok(())
381}
382
383pub fn check_key_not_in_map<K, V>(
389 key: &K,
390 map: &HashMap<K, V>,
391 key_name: &str,
392 map_name: &str,
393) -> anyhow::Result<()>
394where
395 K: Hash + Eq + Display + Clone,
396 V: Debug,
397{
398 if map.contains_key(key) {
399 anyhow::bail!(
400 "the '{key_name}' key {key} was already in the '{map_name}' map `&<{}, {}>`",
401 std::any::type_name::<K>(),
402 std::any::type_name::<V>(),
403 )
404 }
405 Ok(())
406}
407
408pub fn check_key_in_map<K, V>(
414 key: &K,
415 map: &HashMap<K, V>,
416 key_name: &str,
417 map_name: &str,
418) -> anyhow::Result<()>
419where
420 K: Hash + Eq + Display + Clone,
421 V: Debug,
422{
423 if !map.contains_key(key) {
424 anyhow::bail!(
425 "the '{key_name}' key {key} was not in the '{map_name}' map `&<{}, {}>`",
426 std::any::type_name::<K>(),
427 std::any::type_name::<V>(),
428 )
429 }
430 Ok(())
431}
432
433pub fn check_key_not_in_index_map<K, V>(
439 key: &K,
440 map: &IndexMap<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 already in the '{map_name}' map `&<{}, {}>`",
451 std::any::type_name::<K>(),
452 std::any::type_name::<V>(),
453 )
454 }
455 Ok(())
456}
457
458pub fn check_key_in_index_map<K, V>(
464 key: &K,
465 map: &IndexMap<K, V>,
466 key_name: &str,
467 map_name: &str,
468) -> anyhow::Result<()>
469where
470 K: Hash + Eq + Display + Clone,
471 V: Debug,
472{
473 if !map.contains_key(key) {
474 anyhow::bail!(
475 "the '{key_name}' key {key} was not in the '{map_name}' map `&<{}, {}>`",
476 std::any::type_name::<K>(),
477 std::any::type_name::<V>(),
478 )
479 }
480 Ok(())
481}
482
483pub fn check_member_not_in_set<V>(
489 member: &V,
490 set: &HashSet<V>,
491 member_name: &str,
492 set_name: &str,
493) -> anyhow::Result<()>
494where
495 V: Hash + Eq + Display + Clone,
496{
497 if set.contains(member) {
498 anyhow::bail!(
499 "the '{member_name}' member was already in the '{set_name}' set `&<{}>`",
500 std::any::type_name::<V>(),
501 )
502 }
503 Ok(())
504}
505
506pub fn check_member_in_set<V>(
512 member: &V,
513 set: &HashSet<V>,
514 member_name: &str,
515 set_name: &str,
516) -> anyhow::Result<()>
517where
518 V: Hash + Eq + Display + Clone,
519{
520 if !set.contains(member) {
521 anyhow::bail!(
522 "the '{member_name}' member was not in the '{set_name}' set `&<{}>`",
523 std::any::type_name::<V>(),
524 )
525 }
526 Ok(())
527}
528
529#[cfg(test)]
533mod tests {
534 use std::fmt::Display;
535
536 use rstest::rstest;
537
538 use super::*;
539
540 #[rstest]
541 #[case(false, false)]
542 #[case(true, true)]
543 fn test_check_predicate_true(#[case] predicate: bool, #[case] expected: bool) {
544 let result = check_predicate_true(predicate, "the predicate was false").is_ok();
545 assert_eq!(result, expected);
546 }
547
548 #[rstest]
549 #[case(false, true)]
550 #[case(true, false)]
551 fn test_check_predicate_false(#[case] predicate: bool, #[case] expected: bool) {
552 let result = check_predicate_false(predicate, "the predicate was true").is_ok();
553 assert_eq!(result, expected);
554 }
555
556 #[rstest]
557 #[case("a")]
558 #[case(" ")] #[case(" ")] #[case("🦀")] #[case(" a")]
562 #[case("a ")]
563 #[case("abc")]
564 fn test_check_nonempty_string_with_valid_values(#[case] s: &str) {
565 assert!(check_nonempty_string(s, "value").is_ok());
566 }
567
568 #[rstest]
569 #[case("")] fn test_check_nonempty_string_with_invalid_values(#[case] s: &str) {
571 assert!(check_nonempty_string(s, "value").is_err());
572 }
573
574 #[rstest]
575 #[case(" a")]
576 #[case("a ")]
577 #[case("a a")]
578 #[case(" a ")]
579 #[case("abc")]
580 fn test_check_valid_string_with_valid_value(#[case] s: &str) {
581 assert!(check_valid_string(s, "value").is_ok());
582 }
583
584 #[rstest]
585 #[case("")] #[case(" ")] #[case(" ")] #[case("🦀")] fn test_check_valid_string_with_invalid_values(#[case] s: &str) {
590 assert!(check_valid_string(s, "value").is_err());
591 }
592
593 #[rstest]
594 #[case(None)]
595 #[case(Some(" a"))]
596 #[case(Some("a "))]
597 #[case(Some("a a"))]
598 #[case(Some(" a "))]
599 #[case(Some("abc"))]
600 fn test_check_valid_string_optional_with_valid_value(#[case] s: Option<&str>) {
601 assert!(check_valid_string_optional(s, "value").is_ok());
602 }
603
604 #[rstest]
605 #[case("a", "a")]
606 fn test_check_string_contains_when_does_contain(#[case] s: &str, #[case] pat: &str) {
607 assert!(check_string_contains(s, pat, "value").is_ok());
608 }
609
610 #[rstest]
611 #[case("a", "b")]
612 fn test_check_string_contains_when_does_not_contain(#[case] s: &str, #[case] pat: &str) {
613 assert!(check_string_contains(s, pat, "value").is_err());
614 }
615
616 #[rstest]
617 #[case(0u8, 0u8, "left", "right", true)]
618 #[case(1u8, 1u8, "left", "right", true)]
619 #[case(0u8, 1u8, "left", "right", false)]
620 #[case(1u8, 0u8, "left", "right", false)]
621 #[case(10i32, 10i32, "left", "right", true)]
622 #[case(10i32, 20i32, "left", "right", false)]
623 #[case("hello", "hello", "left", "right", true)]
624 #[case("hello", "world", "left", "right", false)]
625 fn test_check_equal<T: PartialEq + Debug + Display>(
626 #[case] lhs: T,
627 #[case] rhs: T,
628 #[case] lhs_param: &str,
629 #[case] rhs_param: &str,
630 #[case] expected: bool,
631 ) {
632 let result = check_equal(lhs, rhs, lhs_param, rhs_param).is_ok();
633 assert_eq!(result, expected);
634 }
635
636 #[rstest]
637 #[case(0, 0, "left", "right", true)]
638 #[case(1, 1, "left", "right", true)]
639 #[case(0, 1, "left", "right", false)]
640 #[case(1, 0, "left", "right", false)]
641 fn test_check_equal_u8_when_equal(
642 #[case] lhs: u8,
643 #[case] rhs: u8,
644 #[case] lhs_param: &str,
645 #[case] rhs_param: &str,
646 #[case] expected: bool,
647 ) {
648 let result = check_equal_u8(lhs, rhs, lhs_param, rhs_param).is_ok();
649 assert_eq!(result, expected);
650 }
651
652 #[rstest]
653 #[case(0, 0, "left", "right", true)]
654 #[case(1, 1, "left", "right", true)]
655 #[case(0, 1, "left", "right", false)]
656 #[case(1, 0, "left", "right", false)]
657 fn test_check_equal_usize_when_equal(
658 #[case] lhs: usize,
659 #[case] rhs: usize,
660 #[case] lhs_param: &str,
661 #[case] rhs_param: &str,
662 #[case] expected: bool,
663 ) {
664 let result = check_equal_usize(lhs, rhs, lhs_param, rhs_param).is_ok();
665 assert_eq!(result, expected);
666 }
667
668 #[rstest]
669 #[case(1, "value")]
670 fn test_check_positive_u64_when_positive(#[case] value: u64, #[case] param: &str) {
671 assert!(check_positive_u64(value, param).is_ok());
672 }
673
674 #[rstest]
675 #[case(0, "value")]
676 fn test_check_positive_u64_when_not_positive(#[case] value: u64, #[case] param: &str) {
677 assert!(check_positive_u64(value, param).is_err());
678 }
679
680 #[rstest]
681 #[case(1, "value")]
682 fn test_check_positive_i64_when_positive(#[case] value: i64, #[case] param: &str) {
683 assert!(check_positive_i64(value, param).is_ok());
684 }
685
686 #[rstest]
687 #[case(0, "value")]
688 #[case(-1, "value")]
689 fn test_check_positive_i64_when_not_positive(#[case] value: i64, #[case] param: &str) {
690 assert!(check_positive_i64(value, param).is_err());
691 }
692
693 #[rstest]
694 #[case(0.0, "value")]
695 #[case(1.0, "value")]
696 fn test_check_non_negative_f64_when_not_negative(#[case] value: f64, #[case] param: &str) {
697 assert!(check_non_negative_f64(value, param).is_ok());
698 }
699
700 #[rstest]
701 #[case(f64::NAN, "value")]
702 #[case(f64::INFINITY, "value")]
703 #[case(f64::NEG_INFINITY, "value")]
704 #[case(-0.1, "value")]
705 fn test_check_non_negative_f64_when_negative(#[case] value: f64, #[case] param: &str) {
706 assert!(check_non_negative_f64(value, param).is_err());
707 }
708
709 #[rstest]
710 #[case(0, 0, 0, "value")]
711 #[case(0, 0, 1, "value")]
712 #[case(1, 0, 1, "value")]
713 fn test_check_in_range_inclusive_u8_when_in_range(
714 #[case] value: u8,
715 #[case] l: u8,
716 #[case] r: u8,
717 #[case] desc: &str,
718 ) {
719 assert!(check_in_range_inclusive_u8(value, l, r, desc).is_ok());
720 }
721
722 #[rstest]
723 #[case(0, 1, 2, "value")]
724 #[case(3, 1, 2, "value")]
725 fn test_check_in_range_inclusive_u8_when_out_of_range(
726 #[case] value: u8,
727 #[case] l: u8,
728 #[case] r: u8,
729 #[case] param: &str,
730 ) {
731 assert!(check_in_range_inclusive_u8(value, l, r, param).is_err());
732 }
733
734 #[rstest]
735 #[case(0, 0, 0, "value")]
736 #[case(0, 0, 1, "value")]
737 #[case(1, 0, 1, "value")]
738 fn test_check_in_range_inclusive_u64_when_in_range(
739 #[case] value: u64,
740 #[case] l: u64,
741 #[case] r: u64,
742 #[case] param: &str,
743 ) {
744 assert!(check_in_range_inclusive_u64(value, l, r, param).is_ok());
745 }
746
747 #[rstest]
748 #[case(0, 1, 2, "value")]
749 #[case(3, 1, 2, "value")]
750 fn test_check_in_range_inclusive_u64_when_out_of_range(
751 #[case] value: u64,
752 #[case] l: u64,
753 #[case] r: u64,
754 #[case] param: &str,
755 ) {
756 assert!(check_in_range_inclusive_u64(value, l, r, param).is_err());
757 }
758
759 #[rstest]
760 #[case(0, 0, 0, "value")]
761 #[case(0, 0, 1, "value")]
762 #[case(1, 0, 1, "value")]
763 fn test_check_in_range_inclusive_i64_when_in_range(
764 #[case] value: i64,
765 #[case] l: i64,
766 #[case] r: i64,
767 #[case] param: &str,
768 ) {
769 assert!(check_in_range_inclusive_i64(value, l, r, param).is_ok());
770 }
771
772 #[rstest]
773 #[case(0.0, 0.0, 0.0, "value")]
774 #[case(0.0, 0.0, 1.0, "value")]
775 #[case(1.0, 0.0, 1.0, "value")]
776 fn test_check_in_range_inclusive_f64_when_in_range(
777 #[case] value: f64,
778 #[case] l: f64,
779 #[case] r: f64,
780 #[case] param: &str,
781 ) {
782 assert!(check_in_range_inclusive_f64(value, l, r, param).is_ok());
783 }
784
785 #[rstest]
786 #[case(-1e16, 0.0, 0.0, "value")]
787 #[case(1.0 + 1e16, 0.0, 1.0, "value")]
788 fn test_check_in_range_inclusive_f64_when_out_of_range(
789 #[case] value: f64,
790 #[case] l: f64,
791 #[case] r: f64,
792 #[case] param: &str,
793 ) {
794 assert!(check_in_range_inclusive_f64(value, l, r, param).is_err());
795 }
796
797 #[rstest]
798 #[case(0, 1, 2, "value")]
799 #[case(3, 1, 2, "value")]
800 fn test_check_in_range_inclusive_i64_when_out_of_range(
801 #[case] value: i64,
802 #[case] l: i64,
803 #[case] r: i64,
804 #[case] param: &str,
805 ) {
806 assert!(check_in_range_inclusive_i64(value, l, r, param).is_err());
807 }
808
809 #[rstest]
810 #[case(0, 0, 0, "value")]
811 #[case(0, 0, 1, "value")]
812 #[case(1, 0, 1, "value")]
813 fn test_check_in_range_inclusive_usize_when_in_range(
814 #[case] value: usize,
815 #[case] l: usize,
816 #[case] r: usize,
817 #[case] param: &str,
818 ) {
819 assert!(check_in_range_inclusive_usize(value, l, r, param).is_ok());
820 }
821
822 #[rstest]
823 #[case(0, 1, 2, "value")]
824 #[case(3, 1, 2, "value")]
825 fn test_check_in_range_inclusive_usize_when_out_of_range(
826 #[case] value: usize,
827 #[case] l: usize,
828 #[case] r: usize,
829 #[case] param: &str,
830 ) {
831 assert!(check_in_range_inclusive_usize(value, l, r, param).is_err());
832 }
833
834 #[rstest]
835 #[case(vec![], true)]
836 #[case(vec![1_u8], false)]
837 fn test_check_slice_empty(#[case] collection: Vec<u8>, #[case] expected: bool) {
838 let result = check_slice_empty(collection.as_slice(), "param").is_ok();
839 assert_eq!(result, expected);
840 }
841
842 #[rstest]
843 #[case(vec![], false)]
844 #[case(vec![1_u8], true)]
845 fn test_check_slice_not_empty(#[case] collection: Vec<u8>, #[case] expected: bool) {
846 let result = check_slice_not_empty(collection.as_slice(), "param").is_ok();
847 assert_eq!(result, expected);
848 }
849
850 #[rstest]
851 #[case(HashMap::new(), true)]
852 #[case(HashMap::from([("A".to_string(), 1_u8)]), false)]
853 fn test_check_map_empty(#[case] map: HashMap<String, u8>, #[case] expected: bool) {
854 let result = check_map_empty(&map, "param").is_ok();
855 assert_eq!(result, expected);
856 }
857
858 #[rstest]
859 #[case(HashMap::new(), false)]
860 #[case(HashMap::from([("A".to_string(), 1_u8)]), true)]
861 fn test_check_map_not_empty(#[case] map: HashMap<String, u8>, #[case] expected: bool) {
862 let result = check_map_not_empty(&map, "param").is_ok();
863 assert_eq!(result, expected);
864 }
865
866 #[rstest]
867 #[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(
871 #[case] map: &HashMap<u32, u32>,
872 #[case] key: u32,
873 #[case] key_name: &str,
874 #[case] map_name: &str,
875 #[case] expected: bool,
876 ) {
877 let result = check_key_not_in_map(&key, map, key_name, map_name).is_ok();
878 assert_eq!(result, expected);
879 }
880
881 #[rstest]
882 #[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(
886 #[case] map: &HashMap<u32, u32>,
887 #[case] key: u32,
888 #[case] key_name: &str,
889 #[case] map_name: &str,
890 #[case] expected: bool,
891 ) {
892 let result = check_key_in_map(&key, map, key_name, map_name).is_ok();
893 assert_eq!(result, expected);
894 }
895
896 #[rstest]
897 #[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(
901 #[case] map: &IndexMap<u32, u32>,
902 #[case] key: u32,
903 #[case] key_name: &str,
904 #[case] map_name: &str,
905 #[case] expected: bool,
906 ) {
907 let result = check_key_not_in_index_map(&key, map, key_name, map_name).is_ok();
908 assert_eq!(result, expected);
909 }
910
911 #[rstest]
912 #[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(
916 #[case] map: &IndexMap<u32, u32>,
917 #[case] key: u32,
918 #[case] key_name: &str,
919 #[case] map_name: &str,
920 #[case] expected: bool,
921 ) {
922 let result = check_key_in_index_map(&key, map, key_name, map_name).is_ok();
923 assert_eq!(result, expected);
924 }
925
926 #[rstest]
927 #[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(
931 #[case] set: &HashSet<u32>,
932 #[case] member: u32,
933 #[case] member_name: &str,
934 #[case] set_name: &str,
935 #[case] expected: bool,
936 ) {
937 let result = check_member_not_in_set(&member, set, member_name, set_name).is_ok();
938 assert_eq!(result, expected);
939 }
940
941 #[rstest]
942 #[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(
946 #[case] set: &HashSet<u32>,
947 #[case] member: u32,
948 #[case] member_name: &str,
949 #[case] set_name: &str,
950 #[case] expected: bool,
951 ) {
952 let result = check_member_in_set(&member, set, member_name, set_name).is_ok();
953 assert_eq!(result, expected);
954 }
955}