use std::borrow::Cow;
use crate::base::{AssertionApi, AssertionResult, AssertionStrategy, Subject};
pub trait CowAssertion<T: ?Sized, Y, R>
{
#[track_caller]
fn is_borrowed(&self) -> R;
#[track_caller]
fn is_owned(&self) -> R;
fn deref(&self) -> Subject<Y, (), R>;
}
impl<'a, T: ?Sized, Y, R> CowAssertion<T, Y, R> for Subject<'a, Cow<'a, T>, (), R>
where
T: ToOwned<Owned=Y>,
AssertionResult: AssertionStrategy<R>,
{
fn is_borrowed(&self) -> R {
if matches!(self.actual(), Cow::Borrowed(_)) {
self.new_result().do_ok()
} else {
self.new_result().add_simple_fact("expected borrowed, but actual was owned").do_fail()
}
}
fn is_owned(&self) -> R {
if matches!(self.actual(), Cow::Owned(_)) {
self.new_result().do_ok()
} else {
self.new_result().add_simple_fact("expected owned, but actual was borrowed").do_fail()
}
}
fn deref(&self) -> Subject<Y, (), R> {
let value = self.actual().as_ref().to_owned();
self.new_owned_subject(value, Some(format!("{}.deref()", self.description_or_expr())), ())
}
}
#[cfg(test)]
mod tests {
use crate::*;
use crate::testing::CheckThatResultAssertion;
use super::*;
#[test]
fn is_borrowed() {
assert_that!(Cow::Borrowed("foobar")).is_borrowed();
assert_that!(check_that!(Cow::<str>::Owned("foobar".to_string())).is_borrowed()).facts_are(
vec![
Fact::new_simple_fact("expected borrowed, but actual was owned")
]
);
}
#[test]
fn is_owned() {
assert_that!(Cow::<str>::Owned("foobar".to_string())).is_owned();
assert_that!(check_that!(Cow::Borrowed("foobar")).is_owned()).facts_are(
vec![
Fact::new_simple_fact("expected owned, but actual was borrowed")
]
);
}
#[test]
fn value() {
assert_that!(Cow::<str>::Owned("foobar".to_string())).deref().is_same_string_to("foobar");
assert_that!(Cow::Borrowed("foobar")).deref().is_same_string_to("foobar");
let owned: Cow<Option<i32>> = Cow::Owned(Some(42));
assert_that!(check_that!(owned).deref().is_none()).facts_are(vec![
Fact::new("value of", "owned.deref()"),
Fact::new("expected", "None"),
Fact::new("actual", "Some(42)"),
]);
}
}