Skip to content

Commit

Permalink
refactor: restructure more code
Browse files Browse the repository at this point in the history
  • Loading branch information
audunhalland committed Mar 17, 2024
1 parent 8d45e42 commit 150648c
Show file tree
Hide file tree
Showing 23 changed files with 558 additions and 588 deletions.
9 changes: 5 additions & 4 deletions src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::call_pattern::*;
use crate::fn_mocker::PatternMatchMode;
use crate::output::{IntoReturn, IntoReturnOnce, Kind, Return, ReturnDefault};
use crate::property::*;
use crate::responder::{Applier, BoxedApplier, IntoReturner};
use crate::responder::{Applier, BoxedApplier, DynResponder, IntoReturner};
use crate::*;
use dyn_builder::*;

Expand All @@ -17,9 +17,10 @@ pub(crate) mod dyn_builder {
use crate::MockFn;

use crate::{
call_pattern::{DynCallOrderResponder, DynInputMatcher, DynResponder},
call_pattern::{DynCallOrderResponder, DynInputMatcher},
counter,
fn_mocker::PatternMatchMode,
responder::DynResponder,
};

// note: appears in public trait signatures
Expand Down Expand Up @@ -270,8 +271,8 @@ macro_rules! define_response_common_impl {
<<F as MockFn>::OutputKind as Kind>::Return: IntoReturner<F>,
{
let default = <<F::OutputKind as Return>::Type as ReturnDefault<
F::OutputKind,
>>::return_default();
F::OutputKind,
>>::return_default();
self.wrapper
.push_returner_result(Ok(default.into_returner()));
self.quantify()
Expand Down
68 changes: 2 additions & 66 deletions src/call_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::alloc::Vec;
use crate::responder::{Applier, BoxedApplier, Returner};
use core::any::Any;
use crate::responder::DynResponder;

use crate::private::MismatchReporter;
use crate::*;
Expand All @@ -24,9 +23,7 @@ pub enum PatternError {

pub type PatternResult<T> = Result<T, PatternError>;

pub(crate) type AnyBox = Box<dyn Any + Send + Sync + 'static>;

fn downcast_box<T: 'static>(any_box: &AnyBox) -> PatternResult<&T> {
pub(crate) fn downcast_box<T: 'static>(any_box: &AnyBox) -> PatternResult<&T> {
any_box.downcast_ref().ok_or(PatternError::Downcast)
}

Expand Down Expand Up @@ -97,67 +94,6 @@ pub(crate) struct DynCallOrderResponder {
pub responder: DynResponder,
}

pub(crate) enum DynResponder {
Return(DynReturnResponder),
StaticApply(DynApplyResponder),
BoxedApply(DynBoxedApplyResponder),
Panic(Box<str>),
Unmock,
CallDefaultImpl,
}

pub(crate) struct DynReturnResponder(AnyBox);
pub(crate) struct DynApplyResponder(AnyBox);
pub(crate) struct DynBoxedApplyResponder(AnyBox);

pub trait DowncastResponder<F: MockFn> {
type Downcasted;

fn downcast(&self) -> PatternResult<&Self::Downcasted>;
}

impl<F: MockFn> DowncastResponder<F> for DynReturnResponder {
type Downcasted = Returner<F>;

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

impl<F: MockFn> DowncastResponder<F> for DynApplyResponder {
type Downcasted = Applier<F>;

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

impl<F: MockFn> DowncastResponder<F> for DynBoxedApplyResponder {
type Downcasted = BoxedApplier<F>;

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

impl<F: MockFn> Returner<F> {
pub(crate) fn into_dyn_responder(self) -> DynResponder {
DynResponder::Return(DynReturnResponder(Box::new(self)))
}
}

impl<F: MockFn> Applier<F> {
pub fn into_dyn_responder(self) -> DynResponder {
DynResponder::StaticApply(DynApplyResponder(Box::new(self)))
}
}

impl<F: MockFn> BoxedApplier<F> {
pub fn into_dyn_responder(self) -> DynResponder {
DynResponder::BoxedApply(DynBoxedApplyResponder(Box::new(self)))
}
}

fn find_responder_by_call_index(
responders: &[DynCallOrderResponder],
call_index: usize,
Expand Down
5 changes: 2 additions & 3 deletions src/eval.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::alloc::{Box, String};
use crate::call_pattern::{
CallPattern, DowncastResponder, DynResponder, PatIndex, PatternError, PatternResult,
};
use crate::call_pattern::{CallPattern, PatIndex, PatternError, PatternResult};
use crate::error::{self};
use crate::error::{MockError, MockResult};
use crate::fn_mocker::{FnMocker, PatternMatchMode};
use crate::mismatch::Mismatches;
use crate::private::{ApplyClosure, Evaluation, MismatchReporter};
use crate::responder::{DowncastResponder, DynResponder};
use crate::state::SharedState;
use crate::{debug, MockFnInfo, Unimock};
use crate::{FallbackMode, MockFn};
Expand Down
9 changes: 6 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ mod responder;
mod state;
mod teardown;

use core::any::Any;
use core::any::TypeId;
use core::fmt::Debug;
use core::panic::RefUnwindSafe;
Expand All @@ -512,7 +513,7 @@ use private::{DefaultImplDelegator, Matching};
use output::IntoRespond;
use output::Kind;

use output::{static_ref::StaticRefResponse, StaticRef};
use output::{static_ref::Reference, StaticRef};

///
/// Autogenerate mocks for all methods in the annotated traits, and `impl` it for [Unimock].
Expand Down Expand Up @@ -1238,8 +1239,8 @@ where
T: core::borrow::Borrow<R> + 'static,
R: Send + Sync + 'static,
{
let response = <T as core::borrow::Borrow<R>>::borrow(Box::leak(Box::new(input)));
Respond(RespondInner::Respond(StaticRefResponse { value: response }))
let reference = <T as core::borrow::Borrow<R>>::borrow(Box::leak(Box::new(input)));
Respond(RespondInner::Respond(Reference(reference)))
}

/// Respond with the unimock instance itself.
Expand All @@ -1252,3 +1253,5 @@ where
unimock.into_respond().unwrap()
}))
}

type AnyBox = Box<dyn Any + Send + Sync + 'static>;
7 changes: 4 additions & 3 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use crate::{alloc::Box, value_chain::ValueChain};

pub(crate) mod deep;
pub(crate) mod lent;
pub(crate) mod mixed;
pub(crate) mod owned;
pub(crate) mod static_ref;

Expand All @@ -27,7 +27,7 @@ pub trait Kind: 'static {
type Respond: for<'u> IntoOutput<Output<'u> = <Self::Return as GetOutput>::Output<'u>>;
}

/// A [Respond] category that may be used with the `returns` combinator.
/// A [Kind] that may be used with `returns` combinators.
pub trait Return: Kind {
/// Type of the return value, as stored inside Unimock.
type Type: 'static;
Expand All @@ -44,6 +44,7 @@ pub trait GetOutput: Sized + 'static {
fn output(&self) -> Option<Self::Output<'_>>;
}

/// A value that can be converted into an output by consuming it.
#[doc(hidden)]
pub trait IntoOutput: Sized + 'static {
type Output<'u>
Expand Down Expand Up @@ -77,7 +78,7 @@ pub trait IntoRespond<K: Kind> {
fn into_respond(self) -> ResponderResult<K::Respond>;
}

pub use deep::Deep;
pub use lent::Lent;
pub use mixed::Mixed;
pub use owned::Owned;
pub use static_ref::StaticRef;
9 changes: 9 additions & 0 deletions src/output/deep/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod option;
mod poll;
mod result;
mod tuples;
mod vec;

/// An output Kind where T is a generic type and some of the parameters are borrows.
#[doc(hidden)]
pub struct Deep<T>(core::marker::PhantomData<T>);
102 changes: 102 additions & 0 deletions src/output/deep/option.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use crate::output::*;

type Mix<K> = Deep<Option<K>>;

impl<K: Kind> Kind for Mix<K> {
type Return = AsReturn<K>;
type Respond = AsRespond<K>;
}

impl<K> Return for Mix<K>
where
K: Return,
<K as Return>::Type: 'static + Send + Sync,
{
type Type = Option<<K as Return>::Type>;
}

impl<T, K: Return> IntoReturnOnce<Mix<K>> for Option<T>
where
<K as Return>::Type: 'static + Send + Sync,
T: IntoReturnOnce<K>,
{
fn into_return_once(self) -> ResponderResult<AsReturn<K>> {
match self {
Some(val) => Ok(AsReturn::Some(val.into_return_once()?)),
None => Ok(AsReturn::None),
}
}
}

impl<T, K: Return> IntoReturn<Mix<K>> for Option<T>
where
<K as Return>::Type: 'static + Send + Sync,
T: IntoReturn<K>,
{
fn into_return(self) -> ResponderResult<AsReturn<K>> {
match self {
Some(val) => Ok(AsReturn::Some(val.into_return()?)),
None => Ok(AsReturn::None),
}
}
}

impl<T, K: Kind> IntoRespond<Mix<K>> for Option<T>
where
T: IntoRespond<K>,
{
fn into_respond(self) -> ResponderResult<AsRespond<K>> {
match self {
Some(val) => Ok(AsRespond::Some(val.into_respond()?)),
None => Ok(AsRespond::None),
}
}
}

pub enum AsReturn<K: Kind> {
Some(K::Return),
None,
}

impl<K: Kind> GetOutput for AsReturn<K>
where
Self: 'static,
{
type Output<'u> =
Option<
<<K as Kind>::Return as GetOutput>::Output<'u>,
>
where
Self: 'u;

fn output(&self) -> Option<Self::Output<'_>> {
match self {
Self::Some(val) => Some(Some(val.output()?)),
Self::None => Some(None),
}
}
}

pub enum AsRespond<K: Kind> {
Some(K::Respond),
None,
}

impl<K: Kind> IntoOutput for AsRespond<K>
where
Self: 'static,
{
type Output<'u> =
Option<
<<K as Kind>::Respond as IntoOutput>::Output<'u>,
>
where
Self: 'u;

fn into_output<'u>(self, value_chain: &'u ValueChain) -> Self::Output<'u> {
match self {
Self::Some(val) => Some(val.into_output(value_chain)),
Self::None => None,
}
}
}
Loading

0 comments on commit 150648c

Please sign in to comment.