reliar-inbox 0.1.0

Transactional inbox deduplication: InboxStore/InboxHandler contracts, claim/complete/fail/purge semantics (no storage or transport dependency).
Documentation
//! The caller's business logic, run between the claim and the completion.

/// What [`crate::InboxStore::process`] runs between the claim and the completion, in the
/// caller's transaction. A trait rather than a closure parameter: an `AsyncFnOnce(&mut Tx)`
/// bound cannot be proven `Send` on stable Rust, and a boxed-future closure fails at the call
/// site โ€” both probed, both in ADR 0042 ยง5. Here the `&mut Tx` lifetime is quantified by
/// `handle` itself, so neither problem exists.
///
/// ```
/// use reliar_inbox::InboxHandler;
///
/// struct RecordOrder;
///
/// impl InboxHandler<()> for RecordOrder {
///     type Output = u64;
///     type Error = std::convert::Infallible;
///
///     async fn handle(&self, _tx: &mut ()) -> Result<Self::Output, Self::Error> {
///         Ok(42)
///     }
/// }
///
/// # #[tokio::main(flavor = "current_thread")]
/// # async fn main() {
/// let output = RecordOrder.handle(&mut ()).await.unwrap();
/// assert_eq!(output, 42);
/// # }
/// ```
pub trait InboxHandler<Tx> {
    /// What the handler produces; returned in [`crate::InboxOutcome::Processed`].
    type Output: Send;

    /// What the handler fails with.
    type Error: std::error::Error + Send + Sync + 'static;

    /// Every write here **shares the caller's transaction** with the inbox completion (and with
    /// any provider `enqueue` the handler makes into an outbox), so they commit together or not
    /// at all โ€” that is the whole of the inbox's guarantee.
    ///
    /// An `Err` means the caller rolls the transaction back: **every** write made here is
    /// undone, including the claim row. Effects the handler causes *outside* the database are
    /// not undone and will happen again on the redelivery.
    ///
    /// SHALL NOT commit, roll back or otherwise consume `tx` โ€” the caller owns it.
    fn handle(
        &self,
        tx: &mut Tx,
    ) -> impl std::future::Future<Output = Result<Self::Output, Self::Error>> + Send;
}