//! This module contains all that is used to create an assertion.
//!
//! The value that will be tested is called the **left element**.
//!
//! # Example
//!
//! ```
//! // Import the needed definitions:
//! use fluid::core::prelude::*;
//!
//! // Create the struct used for the assertion.
//! // The assertion is done in the destructor, so a `Drop` implementation
//! // must be added:
//! #[derive(Drop)]
//! pub struct BeTheAnswer<L: Debug> where L: PartialEq<i32> {
//!     should: Should<L>,
//! }
//!
//! // Implement the trait `AssertionImpl` so that it can be effectively used as
//! // an assertion:
//! impl<L: Debug> AssertionImpl for BeTheAnswer<L> where L: PartialEq<i32> {
//!     // You must specify the type of the left element there:
//!     type Left = L;
//!
//!     // If the test failed, you must return a String with the
//!     // (nicer possible) error message:
//!     fn failure_message(&mut self) -> Option<String> {
//!         let should: &mut ShouldImpl<Self::Left> = (&mut self.should).into();
//!         // The `dbg` method must be used for the style consistency,
//!         // and to shorten the value if it is too long:
//!         let left_dbg = should.left_dbg();
//!         let truthness = should.truthness();
//!
//!         // If the test failed:
//!         if (should.left.as_ref()? == &42) != truthness {
//!             let message = if let Some(stringified) = should.stringified() {
//!                 format!(
//!                     "\t{} is equal to {}.\n\
//!                      \tIt should{} be equal to 42 (the answer).",
//!                     stringified,
//!                     left_dbg,
//!                     truthness,
//!                 )
//!             // A simpler message is created if the left element is not
//!             // stringified:
//!             } else {
//!                 format!(
//!                     "\t{} is{} equal to 42.",
//!                     left_dbg,
//!                     truthness,
//!                 )
//!             };
//!             Some(message)
//!         } else {
//!             None
//!         }
//!     }
//!
//!     // Unfortunately, because virtual fields do not exist in Rust,
//!     // the following 2 methods must be added:
//!
//!     fn consume_as_should(mut self) -> ShouldImpl<Self::Left> {
//!         self.should.take().into()
//!     }
//!
//!     fn should_mut(&mut self) -> &mut ShouldImpl<Self::Left> {
//!         (&mut self.should).into()
//!     }
//! }
//!
//! // You must then create your own extension:
//! pub trait MyAssertionExt<L: Debug> where L: PartialEq<i32> {
//!     fn be_the_answer(self) -> ChainableAssert<BeTheAnswer<L>>;
//! }
//!
//! impl<L: Debug> MyAssertionExt<L> for Should<L> where L: PartialEq<i32> {
//!     fn be_the_answer(self) -> ChainableAssert<BeTheAnswer<L>> {
//!         let implem = BeTheAnswer {
//!             should: self,
//!         };
//!         ChainableAssert(implem)
//!     }
//! }
//!
//! // Now the user can write:
//!
//! use fluid::prelude::*;
//!
//! fn the_meaning_of_life() -> i32 {
//!     42
//! }
//!
//! #[fact]
//! fn the_answer_should_be_ok() {
//!     the_meaning_of_life().should().be_the_answer();
//! }
//! ```

pub mod assert;
mod assertion_impl;
pub(crate) mod display;
pub(crate) mod information;
pub mod should;
mod take;

pub use assertion_impl::AssertionImpl;

/// The things needed to import to create an assertion.
/// See the parent module documentation.
pub mod prelude {
    pub use super::assert::{ChainableAssert, ConsumingAssert};
    pub use super::display::*;
    pub use super::should::{Should, ShouldImpl};
    pub use super::take::Take;
    pub use super::AssertionImpl;
    pub use fluid_attributes::Drop;
    pub use std::fmt::Debug;
}
