InMemoryRepository

Struct InMemoryRepository 

Source
pub struct InMemoryRepository<T: Aggregate>{ /* private fields */ }
Expand description

An in-memory repository implementation that stores events and snapshots in memory.

This repository is useful for testing, development, and scenarios where persistent storage is not required. All data is lost when the repository is dropped.

§Example

use eventastic::memory::InMemoryRepository;
use eventastic::aggregate::{Aggregate, Root, SideEffect};
use eventastic::event::DomainEvent;

// Define a simple aggregate for demonstration
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct Counter {
    id: String,
    count: i32,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum CounterEvent {
    Created { event_id: String, initial_count: i32 },
    Incremented { event_id: String, amount: i32 },
}

impl DomainEvent for CounterEvent {
    type EventId = String;
    fn id(&self) -> &Self::EventId {
        match self {
            CounterEvent::Created { event_id, .. } => event_id,
            CounterEvent::Incremented { event_id, .. } => event_id,
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct CounterSideEffect {
    id: String,
    message: String,
}

impl SideEffect for CounterSideEffect {
    type SideEffectId = String;
    fn id(&self) -> &Self::SideEffectId {
        &self.id
    }
}

impl Aggregate for Counter {
    const SNAPSHOT_VERSION: u64 = 1;
    type AggregateId = String;
    type DomainEvent = CounterEvent;
    type ApplyError = String;
    type SideEffect = CounterSideEffect;

    fn aggregate_id(&self) -> &Self::AggregateId {
        &self.id
    }

    fn apply_new(event: &Self::DomainEvent) -> Result<Self, Self::ApplyError> {
        match event {
            CounterEvent::Created { initial_count, .. } => Ok(Counter {
                id: "counter-1".to_string(),
                count: *initial_count,
            }),
            _ => Err("Counter must start with Created event".to_string()),
        }
    }

    fn apply(&mut self, event: &Self::DomainEvent) -> Result<(), Self::ApplyError> {
        match event {
            CounterEvent::Created { .. } => Err("Counter already exists".to_string()),
            CounterEvent::Incremented { amount, .. } => {
                self.count += amount;
                Ok(())
            }
        }
    }

    fn side_effects(&self, _event: &Self::DomainEvent) -> Option<Vec<Self::SideEffect>> {
        None
    }
}

// Create a repository for your aggregate type
use eventastic::repository::Repository;

let repository: InMemoryRepository<Counter> = InMemoryRepository::new();

// Use transactions to store aggregates
let mut aggregate = Counter::record_new(CounterEvent::Created {
    event_id: "event-1".to_string(),
    initial_count: 0,
})?;

let mut transaction = repository.begin_transaction().await?;
transaction.store(&mut aggregate).await?;
transaction.commit()?;

// Load aggregates using the Repository trait
let loaded = repository.load(&"counter-1".to_string()).await?;
assert_eq!(loaded.state().count, 0);

Implementations§

Source§

impl<T: Aggregate> InMemoryRepository<T>

Source

pub fn new() -> Self

Creates a new empty in-memory repository.

Source

pub fn get_event( &self, aggregate_id: &T::AggregateId, event_id: &<<T as Aggregate>::DomainEvent as DomainEvent>::EventId, ) -> Option<EventStoreEvent<T::DomainEvent>>

Gets a specific event by ID.

Source

pub fn get_events_from( &self, aggregate_id: &T::AggregateId, from_version: u64, ) -> Vec<EventStoreEvent<T::DomainEvent>>

Gets all events for an aggregate starting from a specific version.

Source

pub fn side_effects_count(&self) -> usize

Returns the number of stored side effects.

Source

pub fn get_all_side_effects(&self) -> Vec<T::SideEffect>

Returns all stored side effects.

Source§

impl<T> InMemoryRepository<T>

Source

pub async fn begin_transaction( &self, ) -> Result<InMemoryTransaction<T>, InMemoryError>

Begins a new “transaction” (returns a transaction-like wrapper).

Trait Implementations§

Source§

impl<T: Clone + Aggregate> Clone for InMemoryRepository<T>

Source§

fn clone(&self) -> InMemoryRepository<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Aggregate> Debug for InMemoryRepository<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Aggregate> Default for InMemoryRepository<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T> Repository<T> for InMemoryRepository<T>

Source§

type Error = InMemoryError

The error type returned by the Repository during operations.
Source§

fn load<'life0, 'life1, 'async_trait>( &'life0 self, aggregate_id: &'life1 T::AggregateId, ) -> Pin<Box<dyn Future<Output = Result<Context<T>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Loads an aggregate from the repository by its ID. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.