eventuary-core 0.1.0

Core event model and async IO traits for eventuary
Documentation
use super::{PartitionKey, PartitionKeyResolver};
use crate::error::{Error, Result};
use crate::event::Event;

pub struct MetadataPartitionKeyResolver {
    field: String,
}

impl MetadataPartitionKeyResolver {
    pub fn new(field: impl Into<String>) -> Self {
        Self {
            field: field.into(),
        }
    }
}

impl<P: Send + Sync + 'static> PartitionKeyResolver<P> for MetadataPartitionKeyResolver {
    fn partition_key(&self, event: &Event<P>) -> Result<PartitionKey> {
        match event.metadata().get(&self.field) {
            Some(value) => PartitionKey::new(value),
            None => Err(Error::InvalidEventKey(format!(
                "metadata field '{}' not found",
                self.field
            ))),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::error::Error;
    use crate::event::Event;
    use crate::metadata::Metadata;
    use crate::payload::Payload;

    fn event_with_metadata(field: &str, value: &str) -> Event {
        let metadata = Metadata::new().with(field, value).unwrap();
        Event::builder(
            "acme",
            "/billing",
            "invoice.created",
            "invoice-123",
            Payload::from_string("{}"),
        )
        .unwrap()
        .metadata(metadata)
        .build()
        .unwrap()
    }

    fn event_without_metadata() -> Event {
        Event::create(
            "acme",
            "/billing",
            "invoice.created",
            "invoice-123",
            Payload::from_string("{}"),
        )
        .unwrap()
    }

    #[test]
    fn resolves_metadata_field() {
        let resolver = MetadataPartitionKeyResolver::new("tenant");
        let event = event_with_metadata("tenant", "acme-corp");
        assert_eq!(
            resolver.partition_key(&event).unwrap().as_str(),
            "acme-corp"
        );
    }

    #[test]
    fn rejects_missing_field() {
        let resolver = MetadataPartitionKeyResolver::new("tenant");
        let event = event_without_metadata();
        let err = resolver.partition_key(&event).unwrap_err();
        assert!(matches!(err, Error::InvalidEventKey(_)));
    }
}