Skip to content

Commit

Permalink
Use new responder types
Browse files Browse the repository at this point in the history
  • Loading branch information
audunhalland committed Mar 11, 2024
1 parent cf3c3df commit 397ab6e
Show file tree
Hide file tree
Showing 16 changed files with 1,439 additions and 1,304 deletions.
2 changes: 1 addition & 1 deletion src/assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::alloc::{format, vec, BTreeMap, Entry, String, ToString};
use crate::build::dyn_builder::DynCallPatternBuilder;
use crate::call_pattern::CallPattern;
use crate::fn_mocker::{FnMocker, PatternMatchMode};
use crate::output::ResponderError;
use crate::respond::ResponderError;
use crate::Clause;
use crate::{clause, MockFnInfo};

Expand Down
106 changes: 74 additions & 32 deletions src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ use core::marker::PhantomData;
use crate::alloc::vec;
use crate::call_pattern::*;
use crate::fn_mocker::PatternMatchMode;
use crate::output::{IntoCloneResponder, IntoOnceResponder};
use crate::property::*;
use crate::*;

pub(crate) mod dyn_builder {
use crate::alloc::{vec, Vec};
use crate::output::ResponderError;
use crate::Responder;
use crate::respond::{OutputResponder, ResponderError};
use crate::MockFn;

use crate::{
call_pattern::{DynCallOrderResponder, DynInputMatcher, DynResponder},
Expand Down Expand Up @@ -73,9 +72,24 @@ pub(crate) mod dyn_builder {
}
}

pub fn push_responder_result(&mut self, result: Result<Responder, ResponderError>) {
// pub fn push_responder_result(&mut self, result: Result<Responder, ResponderError>) {
// match result {
// Ok(responder) => self.push_responder(responder.0),
// Err(error) => {
// let dyn_builder = self.inner_mut();
// if dyn_builder.responder_error.is_none() {
// dyn_builder.responder_error = Some(error);
// }
// }
// }
// }

pub fn push_output_responder_result<F: MockFn>(
&mut self,
result: Result<OutputResponder<F>, ResponderError>,
) {
match result {
Ok(responder) => self.push_responder(responder.0),
Ok(responder) => self.push_responder(responder.into_dyn_responder()),
Err(error) => {
let dyn_builder = self.inner_mut();
if dyn_builder.responder_error.is_none() {
Expand Down Expand Up @@ -111,6 +125,7 @@ pub(crate) mod dyn_builder {
}

use crate::alloc::{String, ToString, Vec};
use crate::respond::{IntoMultiResponse, IntoOutputResponder, IntoResponse, Respond};
use dyn_builder::*;

/// Builder for defining a series of cascading call patterns on a specific [MockFn].
Expand Down Expand Up @@ -178,7 +193,7 @@ pub struct DefineResponse<'p, F: MockFn, O: Ordering> {

impl<'p, F: MockFn, O: Ordering> DefineResponse<'p, F, O>
where
<F::Response as Respond>::Type: Send + Sync,
<F::Respond as Respond>::Type: Send + Sync,
{
/// Specify the output of the call pattern by providing a value.
/// The output type cannot contain non-static references.
Expand All @@ -189,7 +204,8 @@ where
/// To be able to return this value multiple times, quantify it explicitly.
pub fn returns<T>(self, value: T) -> QuantifyReturnValue<'p, F, T, O>
where
T: IntoOnceResponder<F::Response>,
T: IntoResponse<F::Respond>,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
QuantifyReturnValue {
wrapper: self.wrapper,
Expand All @@ -215,9 +231,15 @@ where
/// Specify the output of the call pattern by providing a value.
/// The output type cannot contain non-static references.
/// It must also be [Send] and [Sync] because unimock needs to store it, and [Clone] because it should be able to be returned multiple times.
pub fn returns<V: IntoCloneResponder<F::Response>>(mut self, value: V) -> Quantify<'p, F, O> {
self.wrapper
.push_responder_result(value.into_clone_responder::<F>());
pub fn returns<V: IntoMultiResponse<F::Respond>>(mut self, value: V) -> Quantify<'p, F, O>
where
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
self.wrapper.push_output_responder_result(
value
.into_multi_response()
.map(|r| r.into_output_responder()),
);
self.quantify()
}
}
Expand Down Expand Up @@ -248,14 +270,15 @@ macro_rules! define_response_common_impl {
/// Specify the response of the call pattern by calling `Default::default()`.
pub fn returns_default(mut self) -> Quantify<'p, F, O>
where
<F::Response as Respond>::Type: Default,
<F::Respond as Respond>::Type: Default,
{
self.wrapper.push_responder(
InputsFnResponder::<F> {
func: crate::alloc::Box::new(|_| Default::default()),
}
.into_dyn_responder(),
);
// self.wrapper.push_responder(
// InputsFnResponder::<F> {
// func: crate::alloc::Box::new(|_| Default::default()),
// }
// .into_dyn_responder(),
// );
todo!();
self.quantify()
}

Expand Down Expand Up @@ -319,7 +342,8 @@ define_response_common_impl!(DefineMultipleResponses);
pub struct QuantifyReturnValue<'p, F, T, O>
where
F: MockFn,
T: IntoOnceResponder<F::Response>,
T: IntoResponse<F::Respond>,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
pub(crate) wrapper: DynBuilderWrapper<'p>,
return_value: Option<T>,
Expand All @@ -330,15 +354,24 @@ where
impl<'p, F, T, O> QuantifyReturnValue<'p, F, T, O>
where
F: MockFn,
T: IntoOnceResponder<F::Response>,
T: IntoResponse<F::Respond>,
O: Copy,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
/// Expect this call pattern to be matched exactly once.
///
/// This is the only quantifier that works together with return values that don't implement [Clone].
pub fn once(mut self) -> QuantifiedResponse<'p, F, O, Exact> {
self.wrapper
.push_responder_result(self.return_value.take().unwrap().into_once_responder::<F>());
pub fn once(mut self) -> QuantifiedResponse<'p, F, O, Exact>
where
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
self.wrapper.push_output_responder_result(
self.return_value
.take()
.unwrap()
.into_response()
.map(|r| r.into_output_responder()),
);
self.wrapper.quantify(1, counter::Exactness::Exact);
QuantifiedResponse {
wrapper: self.wrapper.steal(),
Expand All @@ -351,13 +384,15 @@ where
/// Expect this call pattern to be matched exactly the specified number of times.
pub fn n_times(mut self, times: usize) -> QuantifiedResponse<'p, F, O, Exact>
where
T: IntoCloneResponder<F::Response>,
T: IntoMultiResponse<F::Respond>,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
self.wrapper.push_responder_result(
self.wrapper.push_output_responder_result(
self.return_value
.take()
.unwrap()
.into_clone_responder::<F>(),
.into_multi_response()
.map(|r| r.into_output_responder()),
);
self.wrapper.quantify(times, counter::Exactness::Exact);
QuantifiedResponse {
Expand All @@ -374,14 +409,16 @@ where
/// Strictly ordered call patterns must have exact quantification.
pub fn at_least_times(mut self, times: usize) -> QuantifiedResponse<'p, F, O, AtLeast>
where
T: IntoCloneResponder<F::Response>,
T: IntoMultiResponse<F::Respond>,
O: Ordering<Kind = InAnyOrder>,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
self.wrapper.push_responder_result(
self.wrapper.push_output_responder_result(
self.return_value
.take()
.unwrap()
.into_clone_responder::<F>(),
.into_multi_response()
.map(|r| r.into_output_responder()),
);
self.wrapper.quantify(times, counter::Exactness::AtLeast);
QuantifiedResponse {
Expand All @@ -396,8 +433,9 @@ where
impl<'p, F, T, O> Clause for QuantifyReturnValue<'p, F, T, O>
where
F: MockFn,
T: IntoOnceResponder<F::Response>,
T: IntoResponse<F::Respond>,
O: Copy + Ordering,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
fn deconstruct(self, sink: &mut dyn clause::term::Sink) -> Result<(), String> {
self.once().deconstruct(sink)
Expand All @@ -412,12 +450,16 @@ where
impl<'p, F, T, O> Drop for QuantifyReturnValue<'p, F, T, O>
where
F: MockFn,
T: IntoOnceResponder<F::Response>,
T: IntoResponse<F::Respond>,
<<F as MockFn>::Respond as Respond>::Get: IntoOutputResponder<F>,
{
fn drop(&mut self) {
if let Some(return_value) = self.return_value.take() {
self.wrapper
.push_responder_result(return_value.into_once_responder::<F>());
self.wrapper.push_output_responder_result(
return_value
.into_response()
.map(|r| r.into_output_responder()),
);
}
}
}
Expand Down
108 changes: 62 additions & 46 deletions src/call_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::alloc::Vec;
use crate::respond::OutputResponder;
use core::any::Any;

use crate::cell::DynCell;
use crate::private::MismatchReporter;
use crate::*;

Expand Down Expand Up @@ -101,13 +101,15 @@ pub(crate) enum DynResponder {
Cell(DynCellResponder),
Borrow(DynBorrowResponder),
InputsFn(DynInputsFnResponder),
Output(DynOutputResponder),
StaticApply(DynStaticApplyResponder),
BoxedApply(DynBoxedApplyResponder),
Panic(Box<str>),
Unmock,
CallDefaultImpl,
}

pub(crate) struct DynOutputResponder(AnyBox);
pub(crate) struct DynCellResponder(AnyBox);
pub(crate) struct DynBorrowResponder(AnyBox);
pub(crate) struct DynInputsFnResponder(AnyBox);
Expand All @@ -120,24 +122,32 @@ pub trait DowncastResponder<F: MockFn> {
fn downcast(&self) -> PatternResult<&Self::Downcasted>;
}

impl<F: MockFn> DowncastResponder<F> for DynCellResponder {
type Downcasted = CellResponder<F>;

fn downcast(&self) -> PatternResult<&Self::Downcasted> {
downcast_box(&self.0)
}
}

impl<F: MockFn> DowncastResponder<F> for DynBorrowResponder {
type Downcasted = BorrowResponder<F>;

fn downcast(&self) -> PatternResult<&Self::Downcasted> {
downcast_box(&self.0)
}
}

impl<F: MockFn> DowncastResponder<F> for DynInputsFnResponder {
type Downcasted = InputsFnResponder<F>;
// impl<F: MockFn> DowncastResponder<F> for DynCellResponder {
// type Downcasted = CellResponder<F>;
//
// fn downcast(&self) -> PatternResult<&Self::Downcasted> {
// downcast_box(&self.0)
// }
// }
//
// impl<F: MockFn> DowncastResponder<F> for DynBorrowResponder {
// type Downcasted = BorrowResponder<F>;
//
// fn downcast(&self) -> PatternResult<&Self::Downcasted> {
// downcast_box(&self.0)
// }
// }

// impl<F: MockFn> DowncastResponder<F> for DynInputsFnResponder {
// type Downcasted = InputsFnResponder<F>;
//
// fn downcast(&self) -> PatternResult<&Self::Downcasted> {
// downcast_box(&self.0)
// }
// }

impl<F: MockFn> DowncastResponder<F> for DynOutputResponder {
type Downcasted = OutputResponder<F>;

fn downcast(&self) -> PatternResult<&Self::Downcasted> {
downcast_box(&self.0)
Expand All @@ -160,18 +170,18 @@ impl<F: MockFn> DowncastResponder<F> for DynBoxedApplyResponder {
}
}

pub(crate) struct CellResponder<F: MockFn> {
pub cell: DynCell<<F::Response as Respond>::Type>,
}

pub(crate) struct BorrowResponder<F: MockFn> {
pub borrowable: <F::Response as Respond>::Type,
}
// pub(crate) struct CellResponder<F: MockFn> {
// pub cell: DynCell<<F::Response as Respond>::Type>,
// }
//
// pub(crate) struct BorrowResponder<F: MockFn> {
// pub borrowable: <F::Response as Respond>::Type,
// }

pub(crate) struct InputsFnResponder<F: MockFn> {
#[allow(clippy::type_complexity)]
pub func: Box<dyn (Fn(F::Inputs<'_>) -> <F::Response as Respond>::Type) + Send + Sync>,
}
// pub(crate) struct InputsFnResponder<F: MockFn> {
// #[allow(clippy::type_complexity)]
// pub func: Box<dyn (Fn(F::Inputs<'_>) -> <F::Response as Respond>::Type) + Send + Sync>,
// }

pub(crate) struct StaticApplyResponder<F: MockFn> {
pub apply_fn: &'static F::ApplyFn,
Expand All @@ -181,26 +191,32 @@ pub(crate) struct BoxedApplyResponder<F: MockFn> {
pub apply_fn: Box<F::ApplyFn>,
}

impl<F: MockFn> CellResponder<F> {
pub fn into_dyn_responder(self) -> DynResponder {
DynResponder::Cell(DynCellResponder(Box::new(self)))
}
}

impl<F: MockFn> BorrowResponder<F>
where
<F::Response as Respond>::Type: Send + Sync,
{
impl<F: MockFn> OutputResponder<F> {
pub fn into_dyn_responder(self) -> DynResponder {
DynResponder::Borrow(DynBorrowResponder(Box::new(self)))
DynResponder::Output(DynOutputResponder(Box::new(self)))
}
}

impl<F: MockFn> InputsFnResponder<F> {
pub fn into_dyn_responder(self) -> DynResponder {
DynResponder::InputsFn(DynInputsFnResponder(Box::new(self)))
}
}
// impl<F: MockFn> CellResponder<F> {
// pub fn into_dyn_responder(self) -> DynResponder {
// DynResponder::Cell(DynCellResponder(Box::new(self)))
// }
// }

// impl<F: MockFn> BorrowResponder<F>
// where
// <F::Response as Respond>::Type: Send + Sync,
// {
// pub fn into_dyn_responder(self) -> DynResponder {
// DynResponder::Borrow(DynBorrowResponder(Box::new(self)))
// }
// }
//
// impl<F: MockFn> InputsFnResponder<F> {
// pub fn into_dyn_responder(self) -> DynResponder {
// DynResponder::InputsFn(DynInputsFnResponder(Box::new(self)))
// }
// }

impl<F: MockFn> StaticApplyResponder<F> {
pub fn into_dyn_responder(self) -> DynResponder {
Expand Down
2 changes: 1 addition & 1 deletion src/cell.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::alloc::Box;
use crate::output::ResponderError;
use crate::respond::ResponderError;

/// A cell that can be "taken from"
pub struct DynCell<T: ?Sized>(Box<dyn TryTake<T>>);
Expand Down
Loading

0 comments on commit 397ab6e

Please sign in to comment.