eventuary-core 0.2.0

Core event model and async IO traits for eventuary
Documentation
use either::Either;

use crate::error::Result;
use crate::io::Acker;
use crate::io::acker::NackContext;

impl<L: Acker, R: Acker> Acker for Either<L, R> {
    async fn ack(&self) -> Result<()> {
        match self {
            Either::Left(a) => a.ack().await,
            Either::Right(a) => a.ack().await,
        }
    }

    async fn nack(&self) -> Result<()> {
        match self {
            Either::Left(a) => a.nack().await,
            Either::Right(a) => a.nack().await,
        }
    }

    async fn nack_with(&self, context: NackContext) -> Result<()> {
        match self {
            Either::Left(a) => a.nack_with(context).await,
            Either::Right(a) => a.nack_with(context).await,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use std::sync::Arc;
    use std::sync::atomic::{AtomicUsize, Ordering};

    struct Counting {
        ack: Arc<AtomicUsize>,
        nack: Arc<AtomicUsize>,
    }

    impl Acker for Counting {
        async fn ack(&self) -> Result<()> {
            self.ack.fetch_add(1, Ordering::SeqCst);
            Ok(())
        }
        async fn nack(&self) -> Result<()> {
            self.nack.fetch_add(1, Ordering::SeqCst);
            Ok(())
        }
    }

    #[tokio::test]
    async fn left_dispatches_to_left() {
        let ack = Arc::new(AtomicUsize::new(0));
        let nack = Arc::new(AtomicUsize::new(0));
        let acker: Either<Counting, Counting> = Either::Left(Counting {
            ack: Arc::clone(&ack),
            nack: Arc::clone(&nack),
        });
        acker.ack().await.unwrap();
        acker.nack().await.unwrap();
        assert_eq!(ack.load(Ordering::SeqCst), 1);
        assert_eq!(nack.load(Ordering::SeqCst), 1);
    }

    #[tokio::test]
    async fn right_dispatches_to_right() {
        let ack = Arc::new(AtomicUsize::new(0));
        let nack = Arc::new(AtomicUsize::new(0));
        let acker: Either<Counting, Counting> = Either::Right(Counting {
            ack: Arc::clone(&ack),
            nack: Arc::clone(&nack),
        });
        acker.ack().await.unwrap();
        acker.nack().await.unwrap();
        assert_eq!(ack.load(Ordering::SeqCst), 1);
        assert_eq!(nack.load(Ordering::SeqCst), 1);
    }
}