summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-03-18 17:14:42 +0100
committerHampusM <hampus@hampusmat.com>2023-03-18 17:15:30 +0100
commitc48271aef7e6b0819c497f302127c161845a83d7 (patch)
treea18d7b5fc8e017b4b7e0917a55534b28a01fe57d /src
parent2ca8017deebe7bfe5aac368aead777a2c4910ca2 (diff)
refactor: rewrite the mock macro as a procedural macro
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs229
1 files changed, 3 insertions, 226 deletions
diff --git a/src/lib.rs b/src/lib.rs
index c4868a2..45aea03 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,196 +1,10 @@
-#[macro_export]
-macro_rules! mock {
- (
- $mock: ident;
+#![deny(clippy::all, clippy::pedantic)]
- impl $mocked_trait: ident for $mocked_trait_target: ident {
- $(
- fn $func: ident$(<
- $($type_param: tt$(: ($($type_param_bound: tt +)+))?),*
- >)?(
- self: ($($self_type: tt)+),
- $($func_param: ident: $func_param_type: ty),*
- )$( -> $return_type: ty)?
- $(where $(
- $where_param: ident: $first_where_param_bound: tt $(+ $where_param_bound: tt)*
- ),*)?;
- )*
- }
- ) => {
- $crate::__private::paste! {
- mod [<__ $mock>] {
- use super::*;
-
- pub struct $mock {
- $(
- [<$func _expectations>]: std::collections::HashMap<
- Vec<$crate::__private::type_id::TypeID>,
- [<$mock Expectation _ $func>]$(<$($crate::__to_unit!($type_param)),*>)?
- >,
- )*
- }
-
- impl $mock
- {
- pub fn new() -> Self
- {
- Self {
- $(
- [<$func _expectations>]: std::collections::HashMap::new()
- ),*
- }
- }
-
- $(
- #[allow(unused)]
- pub(crate) fn [<expect_ $func>]$(<
- $($type_param$(: $($type_param_bound +)*)?),*
- >)?(&mut self)
- -> &mut [<$mock Expectation _ $func>]$(<$($type_param),*>)?
- $(where $(
- $where_param: $first_where_param_bound $(+ $where_param_bound)*
- ),*)?
- {
- let ids = vec![
- $($($crate::__private::type_id::TypeID::of::<$type_param>()),*)?
- ];
-
- let expectation =
- [<$mock Expectation _ $func>]$(::<$($type_param),*>)?::new()
- .strip_type_params();
-
- self.[<$func _expectations>].insert(ids.clone(), expectation);
-
- self.[<$func _expectations>]
- .get_mut(&ids)
- .unwrap()
- .with_type_params_mut()
- }
- )*
- }
-
- impl $mocked_trait for $mock {
- $(
- fn $func$(<$($type_param$(: $($type_param_bound +)+)?),*>)?(
- self: $($self_type)+,
- $($func_param: $func_param_type),*
- )$( -> $return_type)?
- $(where $(
- $where_param: $first_where_param_bound $(+ $where_param_bound)*
- ),*)?
- {
- let ids = vec![
- $($($crate::__private::type_id::TypeID::of::<$type_param>()),*)?
- ];
-
- let expectation = self
- .[<$func _expectations>]
- .get(&ids)
- .expect(concat!(
- "No expectation found for function ",
- stringify!($func)
- ))
- .with_type_params$(::<$($type_param),*>)?();
-
- let Some(returning) = &expectation.returning else {
- panic!(concat!(
- "Expectation for function",
- stringify!($func),
- " is missing a function to call")
- );
- };
-
- returning(self, $($func_param),*)
- }
- )*
- }
-
- $(
- #[allow(non_camel_case_types, non_snake_case)]
- pub struct [<$mock Expectation _ $func>]$(<$($type_param),*>)? {
- returning: Option<
- fn(
- $crate::__replace_ref_type!($($self_type)*, $mock),
- $($func_param_type),*
- )$( -> $return_type)?>,
-
- $(
- $([<$type_param _phantom>]: std::marker::PhantomData<$type_param>,)*
- )?
- }
-
- impl$(<$($type_param),*>)? [<$mock Expectation _ $func>]$(<
- $($type_param),*
- >)? {
- #[allow(unused)]
- fn new() -> Self {
- Self {
- returning: None,
- $(
- $([<$type_param _phantom>]: std::marker::PhantomData,)*
- )?
- }
- }
-
- #[allow(unused)]
- pub fn returning(
- &mut self,
- func: fn(
- $crate::__replace_ref_type!($($self_type)*, $mock),
- $($func_param_type),*
- )$( -> $return_type)?
- ) -> &mut Self
- {
- self.returning = Some(func);
-
- self
- }
-
- #[allow(unused)]
- fn strip_type_params(
- self,
- ) -> [<$mock Expectation _ $func>]$(<$($crate::__to_unit!($type_param)),*>)?
- {
- $crate::__if_empty_else!(($($($type_param)*)?); {
- // No type parameters are present
- self
- }, {
- // Type parameters are present
- unsafe { std::mem::transmute(self) }
- })
-
- }
- }
-
- impl [<$mock Expectation _ $func>]$(<$($crate::__to_unit!($type_param)),*>)? {
- fn with_type_params$(<$($type_param),*>)?(
- &self,
- ) -> &[<$mock Expectation _ $func>]$(<$($type_param),*>)?
- {
- unsafe { &*(self as *const Self).cast() }
- }
-
- #[allow(unused)]
- fn with_type_params_mut$(<$($type_param),*>)?(
- &mut self,
- ) -> &mut [<$mock Expectation _ $func>]$(<$($type_param),*>)?
- {
- unsafe { &mut *(self as *mut Self).cast() }
- }
- }
- )*
- }
-
- use [<__ $mock>]::$mock;
- }
- };
-}
+pub use ridicule_macros::mock;
#[doc(hidden)]
pub mod __private
{
- pub use paste::paste;
-
pub mod type_id
{
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -202,6 +16,7 @@ pub mod __private
impl TypeID
{
#[inline]
+ #[must_use]
pub fn of<T>() -> Self
{
Self {
@@ -210,42 +25,4 @@ pub mod __private
}
}
}
-
- #[macro_export]
- #[doc(hidden)]
- macro_rules! __to_unit {
- ($anything: tt) => {
- ()
- };
- }
-
- #[macro_export]
- #[doc(hidden)]
- macro_rules! __replace_ref_type {
- (&$old_type: tt, $new_type: tt) => {
- &$new_type
- };
-
- (&mut $old_type: tt, $new_type: tt) => {
- &mut $new_type
- };
- }
-
- #[macro_export]
- #[doc(hidden)]
- macro_rules! __if_empty_else {
- (($($input: tt)*); $if_empty: block, $else: block) => {
- $crate::__if_empty_else!(@($($input)*); $if_empty, $else)
- };
-
- // Empty
- (@(); $if_empty: block, $else: block) => {
- $if_empty
- };
-
- // Not empty
- (@($($input: tt)+); $if_empty: block, $else: block) => {
- $else
- };
- }
}