should_be/
lib.rs

1//! Postfix assertions of equality
2//! ```
3//! use should_be::ShouldBe; // Import the trait
4//! let yaks_shaved = 0;
5//! yaks_shaved.should_be(0); // passes
6//! ```
7//! ```should_panic
8//! # use should_be::ShouldBe;
9//! # let yaks_shaved = 0;
10//! yaks_shaved.should_be(1); // panics
11//! // you can provide a panic message using a tuple.
12//! yaks_shaved.should_be((1, "why haven't you shaved?"))
13//! ```
14
15pub trait ShouldBe: PartialEq + std::fmt::Debug + Sized {
16    /// # Panics
17    /// - If `expected != self`.
18    fn should_be(&self, expected: impl ShouldBeArgs<Self>) {
19        match expected.message() {
20            None => assert_eq!(expected.expected(), self),
21            Some(message) => assert_eq!(expected.expected(), self, "{}", message),
22        }
23    }
24}
25
26impl<T> ShouldBe for T where T: PartialEq + std::fmt::Debug + Sized {}
27
28pub trait ShouldBeArgs<T> {
29    type MessageT: std::fmt::Display;
30    fn expected(&self) -> &T;
31    fn message(&self) -> Option<&Self::MessageT> {
32        None
33    }
34}
35
36impl<T> ShouldBeArgs<T> for T {
37    type MessageT = &'static str;
38    fn expected(&self) -> &T {
39        &self
40    }
41}
42
43impl<T> ShouldBeArgs<T> for &T {
44    type MessageT = &'static str;
45    fn expected(&self) -> &T {
46        self
47    }
48}
49
50impl<T, MessageT> ShouldBeArgs<T> for (T, MessageT)
51where
52    MessageT: std::fmt::Display,
53{
54    type MessageT = MessageT;
55    fn expected(&self) -> &T {
56        &self.0
57    }
58
59    fn message(&self) -> Option<&Self::MessageT> {
60        Some(&self.1)
61    }
62}
63
64impl<T, MessageT> ShouldBeArgs<T> for (&T, MessageT)
65where
66    MessageT: std::fmt::Display,
67{
68    type MessageT = MessageT;
69    fn expected(&self) -> &T {
70        self.0
71    }
72
73    fn message(&self) -> Option<&Self::MessageT> {
74        Some(&self.1)
75    }
76}