1pub mod array_like;
2pub mod assertion_hook;
3pub mod empty_types;
4pub mod epsilon_provider;
5pub mod should_result;
6pub mod shoulda_equal;
7pub mod shoulda_of_type;
8pub mod specifics;
9#[cfg(test)]
10mod tests;
11pub mod tuples;
12pub mod wrapper_types;
13
14use crate::assertion_hook::{AssertionHook, NoOpAssertionHook, NotAssertionHook, OrAssertionHook};
15use crate::epsilon_provider::{EnvEpsilonProvider, EpsilonProvider};
16use crate::should_result::ResultsContainer;
17use crate::shoulda_equal::ShouldaEqual;
18use std::fmt::Debug;
19use std::marker::PhantomData;
20use std::ops::DerefMut;
21
22pub struct Should<
24 'a,
25 Inner,
26 Hook: AssertionHook = NoOpAssertionHook,
27 Epsilon: EpsilonProvider = EnvEpsilonProvider,
28> {
29 results: ResultsContainer,
30 inner: &'a Inner,
31 hook: PhantomData<Hook>,
32 float_diff: PhantomData<Epsilon>,
33}
34
35impl<'a, Inner, Hook, Epsilon> Should<'a, Inner, Hook, Epsilon>
36where
37 Hook: AssertionHook,
38 Epsilon: EpsilonProvider,
39{
40 pub(crate) fn internal_assert(&mut self, initial: bool, message: String) {
41 Hook::create_result(initial, message, self.results.deref_mut())
42 }
43 pub(crate) fn change_optional_generics<T: AssertionHook, L: EpsilonProvider>(
44 self,
45 ) -> Should<'a, Inner, T, L> {
46 Should::new(self.inner, self.results)
47 }
48 pub(crate) fn normalize(self) -> Should<'a, Inner, NoOpAssertionHook, Epsilon> {
49 self.change_optional_generics()
50 }
51 pub(crate) fn new(inner: &'a Inner, results: ResultsContainer) -> Self {
52 Self {
53 results,
54 inner,
55 hook: Default::default(),
56 float_diff: Default::default(),
57 }
58 }
59
60 pub fn be(self) -> Self {
62 self
63 }
64
65 pub fn and(self) -> Self {
67 self
68 }
69
70 pub fn float_diff<T: EpsilonProvider>(self) -> Should<'a, Inner, Hook, T> {
72 self.change_optional_generics()
73 }
74}
75
76impl<'a, Inner, Hook, Epsilon> Should<'a, Inner, Hook, Epsilon>
77where
78 Inner: ShouldaEqual + Debug,
79 Hook: AssertionHook,
80 Epsilon: EpsilonProvider,
81{
82 pub fn eq<K: Into<Inner>>(mut self, other: K) -> Self {
84 let other = other.into();
85 self.internal_assert(
86 self.inner.should_eq::<Epsilon>(&other),
87 format!("expected = {:?}, actual = {:?}", &self.inner, other),
88 );
89 self
90 }
91
92 pub fn equal<K: Into<Inner>>(self, other: K) -> Self {
94 self.eq(other)
95 }
96}
97
98impl<'a, Inner, Epsilon> Should<'a, Inner, NoOpAssertionHook, Epsilon>
99where
100 Epsilon: EpsilonProvider,
101{
102 pub fn not(self) -> Should<'a, Inner, NotAssertionHook, Epsilon> {
104 self.change_optional_generics()
105 }
106}
107
108impl<'a, Inner, Epsilon> Should<'a, Inner, NoOpAssertionHook, Epsilon>
109where
110 Epsilon: EpsilonProvider,
111{
112 pub fn or(self) -> Should<'a, Inner, OrAssertionHook, Epsilon> {
115 self.change_optional_generics()
116 }
117}
118
119impl<'a, Inner, Epsilon> Should<'a, Inner, NotAssertionHook, Epsilon>
120where
121 Epsilon: EpsilonProvider,
122{
123 pub fn not(self) -> Should<'a, Inner, NoOpAssertionHook, Epsilon> {
125 self.change_optional_generics()
126 }
127}
128
129pub trait Shoulda {
130 fn should(&self) -> Should<Self>
131 where
132 Self: Sized,
133 {
134 Should::new(self, ResultsContainer::default())
135 }
136}
137
138impl<T> Shoulda for T {}