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> {
#[must_use]
pub fn with_detail_message(self, message: impl Into<String>) -> Self {
self.detail_messages.borrow_mut().push(message.into());
self
}
#[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
}
pub fn add_detail_message(&self, message: impl Into<String>) {
self.detail_messages.borrow_mut().push(message.into());
}
}