shoulda_core/
array_like.rs

1use 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        //TODO: make not dependant on Eq
58        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}