use std::{ops::Deref, slice::Iter, vec::IntoIter};
use chrono::{DateTime, Utc};
use super::event_envelope::EventEnvelope;
use crate::aggregate::Aggregate;
pub struct AggregateEvents<A>
where
A: Aggregate,
{
events: Vec<EventEnvelope<A>>,
}
impl<A> AggregateEvents<A>
where
A: Aggregate,
{
pub fn new(events: Vec<EventEnvelope<A>>) -> Self {
Self { events }
}
pub fn created_by(&self) -> Option<String> {
self.events
.first()
.and_then(|e| e.context.actor_id().map(|s| s.to_string()))
}
pub fn last_modified_by(&self) -> Option<String> {
self.events
.last()
.and_then(|e| e.context.actor_id().map(|s| s.to_string()))
}
pub fn created_at(&self) -> Option<DateTime<Utc>> {
self.events.first().map(|e| *e.metadata.occurred_at())
}
pub fn last_modified_at(&self) -> Option<DateTime<Utc>> {
self.events.last().map(|e| *e.metadata.occurred_at())
}
pub fn events(&self) -> &[EventEnvelope<A>] {
&self.events
}
pub fn len(&self) -> usize {
self.events.len()
}
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
pub fn iter(&self) -> Iter<'_, EventEnvelope<A>> {
self.events.iter()
}
}
impl<A> IntoIterator for AggregateEvents<A>
where
A: Aggregate,
{
type Item = EventEnvelope<A>;
type IntoIter = IntoIter<EventEnvelope<A>>;
fn into_iter(self) -> Self::IntoIter {
self.events.into_iter()
}
}
impl<'a, A> IntoIterator for &'a AggregateEvents<A>
where
A: Aggregate,
{
type Item = &'a EventEnvelope<A>;
type IntoIter = Iter<'a, EventEnvelope<A>>;
fn into_iter(self) -> Self::IntoIter {
self.events.iter()
}
}
impl<A> Deref for AggregateEvents<A>
where
A: Aggregate,
{
type Target = [EventEnvelope<A>];
fn deref(&self) -> &Self::Target {
&self.events
}
}