mockiato 0.9.6

A strict, yet friendly mocking library for Rust 2018
Documentation
use super::ReturnValueGenerator;
use crate::fmt::MaybeDebug;
use crate::matcher::ArgumentsMatcher;
use std::cell::RefCell;
use std::fmt::{self, Debug, Display};

pub(crate) struct Once<T>(RefCell<Option<T>>);

impl<T> Once<T> {
    pub(crate) fn new(value: T) -> Self {
        Self(RefCell::new(Some(value)))
    }
}

impl<A, R> ReturnValueGenerator<A, R> for Once<R>
where
    A: for<'args> ArgumentsMatcher<'args>,
{
    fn generate_return_value(&self, _: <A as ArgumentsMatcher<'_>>::Arguments) -> R {
        self.0
            .borrow_mut()
            .take()
            .expect("This value was already returned")
    }

    fn can_return_more_than_once(&self) -> bool {
        false
    }
}

impl<R> Display for Once<R>
where
    R: MaybeDebug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        MaybeDebug::fmt(&self.0, f)
    }
}

impl<R> Debug for Once<R>
where
    R: MaybeDebug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        MaybeDebug::fmt(&self.0, f)
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::arguments::ArgumentsMock;
    use crate::matcher::ArgumentsMatcherMock;

    #[test]
    fn returns_expected_value() {
        let return_value = Once::new(String::from("foo"));

        assert_eq!(
            String::from("foo"),
            ReturnValueGenerator::<ArgumentsMatcherMock, String>::generate_return_value(
                &return_value,
                ArgumentsMock
            )
        );
    }

    #[test]
    #[should_panic]
    fn panics_when_called_more_than_once() {
        let return_value = Once::new(String::from("foo"));

        assert_eq!(
            String::from("foo"),
            ReturnValueGenerator::<ArgumentsMatcherMock, _>::generate_return_value(
                &return_value,
                ArgumentsMock
            )
        );

        ReturnValueGenerator::<ArgumentsMatcherMock, _>::generate_return_value(
            &return_value,
            ArgumentsMock,
        );
    }
}