use std::ops::Deref;
use std::time::SystemTime;
use uuid::Uuid;
use crate::envelope::{Envelope, TryFromEnvelope};
use crate::event::{self, Sequence};
use crate::{error, EventGroup};
pub struct Context<'de, E, G> {
envelope: &'de E,
event_group: G,
}
#[trait_variant::make(Send)]
pub trait Project<'de>: Send + Clone {
type EventGroup: event::EventGroup + TryFromEnvelope<'de>;
type Error: std::error::Error + Send + Sync + 'static;
async fn project<E>(
&mut self,
context: Context<'de, E, Self::EventGroup>,
) -> Result<(), Self::Error>
where
E: Envelope + Sync;
}
impl<'de, E, G> Context<'de, E, G>
where
E: Envelope,
G: EventGroup + TryFromEnvelope<'de>,
{
pub fn try_with_envelope(envelope: &'de E) -> error::Result<Self> {
Ok(Self {
envelope,
event_group: G::try_from_envelope(envelope)?,
})
}
}
impl<'de, E: Envelope, G> Context<'de, E, G> {
pub fn id(this: &Self) -> Uuid {
this.envelope.id()
}
pub fn sequence(this: &Self) -> Sequence {
this.envelope.sequence()
}
pub fn timestamp(this: &Self) -> SystemTime {
this.envelope.timestamp()
}
pub fn into_inner(this: Self) -> G {
this.event_group
}
}
impl<'de, E, G> Deref for Context<'de, E, G> {
type Target = G;
fn deref(&self) -> &Self::Target {
&self.event_group
}
}