use crate::{
matcher::InvocationMatcher,
mock::{self, stub, Stub},
};
pub struct Once<'m, R, I, O, M: InvocationMatcher<I>> {
id: fn(R, I) -> O,
name: &'static str,
store: &'m mut mock::Store<'static>,
matcher: M,
}
impl<'m, R, I, O, M: InvocationMatcher<I> + Send + 'static> Once<'m, R, I, O, M> {
#[doc(hidden)]
pub fn new(
id: fn(R, I) -> O,
name: &'static str,
store: &'m mut mock::Store<'static>,
matcher: M,
) -> Self {
Once {
id,
name,
store,
matcher,
}
}
pub fn then_return(self, value: O)
where
O: 'static + Send,
{
unsafe { self.then_unchecked_return(value) }
}
pub fn then(self, stub: impl FnOnce(I) -> O + 'static + Send)
where
O: 'static,
{
self.add_stub(Box::new(stub))
}
pub unsafe fn then_unchecked_return(self, value: O)
where
O: Send,
{
self.then_unchecked(move |_: I| value)
}
pub unsafe fn then_unchecked(self, stub: impl FnOnce(I) -> O + Send) {
let stub: Box<dyn FnOnce(I) -> O + Send> = Box::new(stub);
let stub: Box<_> = std::mem::transmute(stub);
self.add_stub(stub);
}
fn add_stub(self, stub: Box<dyn FnOnce(I) -> O + Send + 'static>) {
self.store
.get_mut(self.id, self.name)
.add_stub(Stub::new(stub::Answer::Once(stub), self.matcher));
}
}