kernal/collections/partial_eq/btree.rs
1//! Contains equality-based assertions for [Collection]s with items that implement [Eq] and [Ord],
2//! using the additional constraints to optimize runtime. See [CollectionEqOrdAssertions] for more
3//! details.
4
5use std::borrow::Borrow;
6use std::collections::BTreeSet;
7use std::fmt::Debug;
8
9use crate::AssertThat;
10use crate::collections::Collection;
11use crate::collections::partial_eq::{
12 check_contains_all_of,
13 check_contains_exactly_in_any_order,
14 check_contains_none_of
15};
16use crate::util::borrow_all;
17use crate::util::multiset::btree::BTreeMultiset;
18
19/// An extension trait to be used on the output of [assert_that](crate::assert_that) with an
20/// argument that implements the [Collection] trait where the [Collection::Item] type implements
21/// [Eq] and [Ord] in addition to the required [Debug] trait. It offers optimized assertions which
22/// benefit from the additional [Ord] constraint in terms of runtime.
23///
24/// Examples:
25///
26/// ```
27/// use kernal::prelude::*;
28/// use kernal::fast_prelude::*;
29///
30/// assert_that!(&[2, 3, 5, 7, 11])
31/// .contains_exactly_in_any_order_using_ord([3, 7, 2, 11, 5])
32/// .contains_none_of_using_ord([4, 6, 8, 10, 12]);
33/// ```
34pub trait CollectionEqOrdAssertions<'collection, C>
35where
36 C: Collection<'collection>
37{
38 /// Asserts that for each of the given `items`, the tested collection contains an equal element
39 /// according to [Eq] and [Ord]. If the provided iterator contains multiple equal elements, this
40 /// function asserts that the tested collection contains at least that number of equal elements,
41 /// so `[1, 1, 2]` contains all of `[1, 1]`, but not all of `[1, 1, 1]`.
42 ///
43 /// This can be considered a faster alternative to
44 /// [CollectionPartialEqAssertions::contains_all_of](crate::collections::partial_eq::CollectionPartialEqAssertions::contains_all_of)
45 /// with the trade-off of additional trait bounds.
46 fn contains_all_of_using_ord<E, I>(self, items: I) -> Self
47 where
48 E: Borrow<C::Item>,
49 I: IntoIterator<Item = E>;
50
51 /// Asserts that the tested collection contains no element which is equal to one the given
52 /// `items` according to [Eq] and [Ord].
53 ///
54 /// This can be considered a faster alternative to
55 /// [CollectionPartialEqAssertions::contains_none_of](crate::collections::partial_eq::CollectionPartialEqAssertions::contains_none_of)
56 /// with the trade-off of additional trait bounds.
57 fn contains_none_of_using_ord<E, I>(self, items: I) -> Self
58 where
59 E: Borrow<C::Item>,
60 I: IntoIterator<Item = E>;
61
62 /// Asserts that there is a one-to-one matching of the given `items` and the elements of the
63 /// tested collection such that matched elements are equal according to [Eq] and [Ord].
64 ///
65 /// This can be considered a faster alternative to
66 /// [CollectionPartialEqAssertions::contains_exactly_in_any_order](crate::collections::partial_eq::CollectionPartialEqAssertions::contains_exactly_in_any_order)
67 /// with the trade-off of additional trait bounds.
68 fn contains_exactly_in_any_order_using_ord<E, I>(self, items: I) -> Self
69 where
70 E: Borrow<C::Item>,
71 I: IntoIterator<Item = E>;
72}
73
74impl<'collection, C> CollectionEqOrdAssertions<'collection, C> for AssertThat<C>
75where
76 C: Collection<'collection>,
77 C::Item: Debug + Eq + Ord
78{
79 fn contains_all_of_using_ord<E, I>(self, items: I) -> Self
80 where
81 E: Borrow<C::Item>,
82 I: IntoIterator<Item = E>
83 {
84 let expected_items_unborrowed = items.into_iter().collect::<Vec<_>>();
85 let expected_items: Vec<&C::Item> = borrow_all(&expected_items_unborrowed);
86
87 check_contains_all_of::<_, _, BTreeMultiset<_>>(&self, self.data.iterator(), &expected_items);
88
89 self
90 }
91
92 fn contains_none_of_using_ord<E, I>(self, items: I) -> Self
93 where
94 E: Borrow<C::Item>,
95 I: IntoIterator<Item = E>
96 {
97 let unexpected_items_unborrowed = items.into_iter().collect::<Vec<_>>();
98 let unexpected_items: Vec<&C::Item> = borrow_all(&unexpected_items_unborrowed);
99
100 check_contains_none_of::<_, _, BTreeSet<_>>(&self, self.data.iterator(), unexpected_items);
101
102 self
103 }
104
105 fn contains_exactly_in_any_order_using_ord<E, I>(self, items: I) -> Self
106 where
107 E: Borrow<C::Item>,
108 I: IntoIterator<Item = E>
109 {
110 let expected_items_unborrowed = items.into_iter().collect::<Vec<_>>();
111 let expected_items: Vec<&C::Item> = borrow_all(&expected_items_unborrowed);
112
113 check_contains_exactly_in_any_order::<_, _, BTreeMultiset<_>>(
114 &self, self.data.iterator(), &expected_items);
115
116 self
117 }
118}
119
120#[cfg(test)]
121mod tests {
122
123 use crate::{
124 assert_fails,
125 test_contains_all_of,
126 test_contains_exactly_in_any_order,
127 test_contains_none_of
128 };
129 use crate::prelude::*;
130
131 use super::*;
132
133 test_contains_all_of!(contains_all_of_using_ord);
134
135 test_contains_none_of!(contains_none_of_using_ord);
136
137 test_contains_exactly_in_any_order!(contains_exactly_in_any_order_using_ord);
138}