assertr 0.5.4

Fluent assertions for the Rust programming language.
Documentation
use alloc::borrow::ToOwned;
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt::Debug;

use crate::{AssertThat, mode::Mode};

pub(crate) struct DetailMessages<'a>(pub(crate) &'a [String]);

impl Debug for DetailMessages<'_> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_list()
            .entries(self.0.iter().map(|it| DisplayString(it)))
            .finish()
    }
}

pub(crate) struct DisplayString<'a>(pub(crate) &'a str);

impl Debug for DisplayString<'_> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.write_str(self.0)
    }
}

pub(crate) trait WithDetail {
    fn collect_messages(&self, collection: &mut Vec<String>);
}

impl<T, M: Mode> WithDetail for AssertThat<'_, T, M> {
    fn collect_messages(&self, collection: &mut Vec<String>) {
        for m in self.detail_messages.borrow().iter() {
            collection.push(m.to_owned());
        }
        if let Some(parent) = self.parent {
            parent.collect_messages(collection);
        }
    }
}

impl<T, M: Mode> AssertThat<'_, T, M> {
    /// Add a message to be displayed on assertion failure.
    #[must_use]
    pub fn with_detail_message(self, message: impl Into<String>) -> Self {
        self.detail_messages.borrow_mut().push(message.into());
        self
    }

    /// Add a message to be displayed on assertion failure bound by the given condition.
    #[must_use]
    pub fn with_conditional_detail_message<Message: Into<String>>(
        self,
        condition: impl Fn(&Self) -> bool,
        message_provider: impl Fn(&Self) -> Message,
    ) -> Self {
        if condition(&self) {
            let message = message_provider(&self);
            self.detail_messages.borrow_mut().push(message.into());
        }
        self
    }

    /// Add a message to be displayed on assertion failure.
    ///
    /// Use this variant instead of the `with_` variants when not in a call-chain context,
    /// and you don't want to call an ownership-taking function.
    pub fn add_detail_message(&self, message: impl Into<String>) {
        self.detail_messages.borrow_mut().push(message.into());
    }
}