pub use crate::settings::{Merge, Push, Set, Unset};
pub trait Declaration {
type Form;
type Message;
type Key;
type Attempt;
type Headers;
type RetryAfter;
type ProcessedAt;
type Clock;
type Opening;
type Fifo;
type OwnClaim;
type OwnFetch;
type OwnAck;
type OwnRetry;
type OwnRetryAfter;
type OwnDiscard;
type OwnDeadLetter;
type OwnExtend;
type OwnLock;
type OwnUnlock;
}
macro_rules! setting {
($(#[$doc:meta])* $name:ident $(<$param:ident>)?, $slot:ident) => {
$(#[$doc])*
#[derive(Debug)]
pub struct $name$(<$param>(PhantomData<fn() -> $param>))?;
impl$(<$param>)? Declaration for $name$(<$param>)? {
setting!(@slots $slot, Set<Self>;
Form Message Key Attempt Headers RetryAfter ProcessedAt Clock Opening Fifo
OwnClaim OwnFetch OwnAck OwnRetry OwnRetryAfter OwnDiscard OwnDeadLetter
OwnExtend OwnLock OwnUnlock);
}
};
(@slots $slot:ident, $value:ty; $($each:ident)*) => {
$(setting!(@slot $slot, $value; $each);)*
};
(@slot Form, $value:ty; Form) => { type Form = $value; };
(@slot Message, $value:ty; Message) => { type Message = $value; };
(@slot Key, $value:ty; Key) => { type Key = $value; };
(@slot Attempt, $value:ty; Attempt) => { type Attempt = $value; };
(@slot Headers, $value:ty; Headers) => { type Headers = $value; };
(@slot RetryAfter, $value:ty; RetryAfter) => { type RetryAfter = $value; };
(@slot ProcessedAt, $value:ty; ProcessedAt) => { type ProcessedAt = $value; };
(@slot Clock, $value:ty; Clock) => { type Clock = $value; };
(@slot Opening, $value:ty; Opening) => { type Opening = $value; };
(@slot Fifo, $value:ty; Fifo) => { type Fifo = $value; };
(@slot OwnClaim, $value:ty; OwnClaim) => { type OwnClaim = $value; };
(@slot OwnFetch, $value:ty; OwnFetch) => { type OwnFetch = $value; };
(@slot OwnAck, $value:ty; OwnAck) => { type OwnAck = $value; };
(@slot OwnRetry, $value:ty; OwnRetry) => { type OwnRetry = $value; };
(@slot OwnRetryAfter, $value:ty; OwnRetryAfter) => { type OwnRetryAfter = $value; };
(@slot OwnDiscard, $value:ty; OwnDiscard) => { type OwnDiscard = $value; };
(@slot OwnDeadLetter, $value:ty; OwnDeadLetter) => { type OwnDeadLetter = $value; };
(@slot OwnExtend, $value:ty; OwnExtend) => { type OwnExtend = $value; };
(@slot OwnLock, $value:ty; OwnLock) => { type OwnLock = $value; };
(@slot OwnUnlock, $value:ty; OwnUnlock) => { type OwnUnlock = $value; };
(@slot $slot:ident, $value:ty; $other:ident) => { type $other = Unset; };
}
pub(super) use setting;
impl Declaration for () {
type Form = Unset;
type Message = Unset;
type Key = Unset;
type Attempt = Unset;
type Headers = Unset;
type RetryAfter = Unset;
type ProcessedAt = Unset;
type Clock = Unset;
type Opening = Unset;
type Fifo = Unset;
type OwnClaim = Unset;
type OwnFetch = Unset;
type OwnAck = Unset;
type OwnRetry = Unset;
type OwnRetryAfter = Unset;
type OwnDiscard = Unset;
type OwnDeadLetter = Unset;
type OwnExtend = Unset;
type OwnLock = Unset;
type OwnUnlock = Unset;
}
macro_rules! tuple {
($head:ident $(, $tail:ident)*) => {
tuple!(@impl [$head $(, $tail)*] $head, ($($tail,)*);
Form Message Key Attempt Headers RetryAfter ProcessedAt Clock Opening Fifo
OwnClaim OwnFetch OwnAck OwnRetry OwnRetryAfter OwnDiscard OwnDeadLetter
OwnExtend OwnLock OwnUnlock);
};
(@impl [$($each:ident),*] $head:ident, $tail:ty; $($slot:ident)*) => {
impl<$($each: Declaration),*> Declaration for ($($each,)*)
where
$tail: Declaration,
$($head::$slot: Merge<<$tail as Declaration>::$slot>,)*
{
$(type $slot = <$head::$slot as Merge<<$tail as Declaration>::$slot>>::Out;)*
}
};
}
tuple!(Setting1);
tuple!(Setting1, Setting2);
tuple!(Setting1, Setting2, Setting3);
tuple!(Setting1, Setting2, Setting3, Setting4);
tuple!(Setting1, Setting2, Setting3, Setting4, Setting5);
tuple!(Setting1, Setting2, Setting3, Setting4, Setting5, Setting6);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14, Setting15
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14, Setting15, Setting16
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14, Setting15, Setting16, Setting17
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14, Setting15, Setting16, Setting17,
Setting18
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14, Setting15, Setting16, Setting17,
Setting18, Setting19
);
tuple!(
Setting1, Setting2, Setting3, Setting4, Setting5, Setting6, Setting7, Setting8, Setting9,
Setting10, Setting11, Setting12, Setting13, Setting14, Setting15, Setting16, Setting17,
Setting18, Setting19, Setting20
);
#[cfg(test)]
mod tests {
use std::any::TypeId;
use std::time::SystemTime;
use super::{Declaration, Set, Unset};
use crate::SystemClock;
use crate::inbox::spec::{
Attempt, Clock, Fifo, Headers, Key, Lease, Payload, ProcessedAt, RetryAfter, own,
};
fn same<Left: 'static, Right: 'static>() -> bool {
TypeId::of::<Left>() == TypeId::of::<Right>()
}
#[test]
fn a_lease_table_folds_each_setting_into_its_own_slot() {
type Settings = (
Lease<SystemTime>,
Payload,
Attempt,
RetryAfter<SystemTime>,
ProcessedAt<SystemTime>,
Key,
);
assert!(same::<
<Settings as Declaration>::Form,
Set<Lease<SystemTime>>,
>());
assert!(same::<<Settings as Declaration>::Message, Set<Payload>>());
assert!(same::<<Settings as Declaration>::Key, Set<Key>>());
assert!(same::<<Settings as Declaration>::Attempt, Set<Attempt>>());
assert!(same::<
<Settings as Declaration>::RetryAfter,
Set<RetryAfter<SystemTime>>,
>());
assert!(same::<
<Settings as Declaration>::ProcessedAt,
Set<ProcessedAt<SystemTime>>,
>());
assert!(same::<<Settings as Declaration>::Headers, Unset>());
assert!(same::<<Settings as Declaration>::Clock, Unset>());
assert!(same::<<Settings as Declaration>::OwnAck, Unset>());
}
#[test]
fn an_own_event_folds_into_its_own_slot() {
type Settings = (Fifo, Headers, own::Ack, Clock<SystemClock>);
assert!(same::<<Settings as Declaration>::OwnAck, Set<own::Ack>>());
assert!(same::<<Settings as Declaration>::Fifo, Set<Fifo>>());
assert!(same::<<Settings as Declaration>::OwnClaim, Unset>());
assert!(same::<<Settings as Declaration>::Form, Unset>());
}
}