shoulda_core/
array_like.rs1use crate::epsilon_provider::EpsilonProvider;
2use crate::ShouldaEqual;
3use std::collections::{HashMap, HashSet, VecDeque};
4use std::fmt::Debug;
5use std::hash::Hash;
6use std::ops::{Range, RangeInclusive};
7
8macro_rules! zip_all_test_eq_assertable_impl {
9 ($x:ty) => {
10 impl<T> ShouldaEqual for $x
11 where
12 T: Debug,
13 T: ShouldaEqual,
14 {
15 fn should_eq<Epsilon: EpsilonProvider>(&self, other: &Self) -> bool {
16 self.iter()
17 .zip(other.iter())
18 .all(|(a, b)| a.should_eq::<Epsilon>(b))
19 }
20 }
21 };
22}
23
24zip_all_test_eq_assertable_impl!(Vec<T>);
25zip_all_test_eq_assertable_impl!(VecDeque<T>);
26zip_all_test_eq_assertable_impl!(&[T]);
27zip_all_test_eq_assertable_impl!([T]);
28
29impl<T, K> ShouldaEqual for HashMap<T, K>
30where
31 T: Debug,
32 T: ShouldaEqual,
33 T: Eq,
34 T: Hash,
35 K: Debug,
36 K: ShouldaEqual,
37{
38 fn should_eq<Epsilon: EpsilonProvider>(&self, other: &Self) -> bool {
39 self.len() == other.len()
40 && self.keys().all(|x| {
41 other
42 .get(x)
43 .map(|v| v.should_eq::<Epsilon>(&self[x]))
44 .unwrap_or(false)
45 })
46 }
47}
48
49impl<T> ShouldaEqual for HashSet<T>
50where
51 T: Debug,
52 T: ShouldaEqual,
53 T: Eq,
54 T: Hash,
55{
56 fn should_eq<Epsilon: EpsilonProvider>(&self, other: &Self) -> bool {
57 self.iter().all(|x| other.contains(x))
59 }
60}
61
62impl<T> ShouldaEqual for Range<T>
63where
64 T: Debug,
65 T: ShouldaEqual,
66{
67 fn should_eq<Epsilon: EpsilonProvider>(&self, other: &Self) -> bool {
68 self.start.should_eq::<Epsilon>(&other.start) && self.end.should_eq::<Epsilon>(&other.end)
69 }
70}
71
72impl<T> ShouldaEqual for RangeInclusive<T>
73where
74 T: Debug,
75 T: ShouldaEqual,
76{
77 fn should_eq<Epsilon: EpsilonProvider>(&self, other: &Self) -> bool {
78 self.start().should_eq::<Epsilon>(other.start())
79 && self.end().should_eq::<Epsilon>(other.end())
80 }
81}