use crate::aggregate::AggregateRepository;
use crate::outbox::OutboxPublisherConfig;
use crate::repository::{ReadModelWritePlanStore, RelationalReadModelQueryStore, Repository};
pub trait HasRepo {
type Repo;
fn repo(&self) -> &Self::Repo;
}
pub trait HasReadModelStore {
type ReadModelStore;
fn read_model_store(&self) -> &Self::ReadModelStore;
}
pub trait ConfigurableOutboxPublisher {
fn configure_outbox_publisher(&mut self, config: OutboxPublisherConfig);
}
impl<R, A> ConfigurableOutboxPublisher for AggregateRepository<R, A> {
fn configure_outbox_publisher(&mut self, config: OutboxPublisherConfig) {
self.set_outbox_publisher(config);
}
}
impl<R: ConfigurableOutboxPublisher, S> ConfigurableOutboxPublisher
for RepoReadModelDependencies<R, S>
{
fn configure_outbox_publisher(&mut self, config: OutboxPublisherConfig) {
self.repo.configure_outbox_publisher(config);
}
}
impl<R: HasOutboxStore, S> HasOutboxStore for RepoReadModelDependencies<R, S> {
type OutboxStore = R::OutboxStore;
fn outbox_store(&self) -> Self::OutboxStore {
self.repo().outbox_store()
}
}
pub trait HasOutboxStore {
type OutboxStore: crate::outbox_worker::OutboxStore;
fn outbox_store(&self) -> Self::OutboxStore;
}
impl HasOutboxStore for crate::HashMapRepository {
type OutboxStore = crate::HashMapOutboxStore;
fn outbox_store(&self) -> Self::OutboxStore {
crate::HashMapRepository::outbox_store(self)
}
}
#[cfg(feature = "sqlite")]
impl HasOutboxStore for crate::SqliteRepository {
type OutboxStore = crate::SqliteOutboxStore;
fn outbox_store(&self) -> Self::OutboxStore {
crate::SqliteRepository::outbox_store(self)
}
}
#[cfg(feature = "postgres")]
impl HasOutboxStore for crate::PostgresRepository {
type OutboxStore = crate::PostgresOutboxStore;
fn outbox_store(&self) -> Self::OutboxStore {
crate::PostgresRepository::outbox_store(self)
}
}
impl<R, A> HasOutboxStore for AggregateRepository<R, A>
where
R: HasOutboxStore,
{
type OutboxStore = R::OutboxStore;
fn outbox_store(&self) -> Self::OutboxStore {
self.repo().outbox_store()
}
}
impl<R, L> HasOutboxStore for crate::QueuedRepository<R, L>
where
R: HasOutboxStore,
{
type OutboxStore = R::OutboxStore;
fn outbox_store(&self) -> Self::OutboxStore {
self.inner().outbox_store()
}
}
impl<R> HasRepo for R
where
R: Repository,
{
type Repo = R;
fn repo(&self) -> &Self::Repo {
self
}
}
impl<R, A> HasRepo for AggregateRepository<R, A> {
type Repo = Self;
fn repo(&self) -> &Self::Repo {
self
}
}
impl<S> HasReadModelStore for S
where
S: ReadModelWritePlanStore + RelationalReadModelQueryStore,
{
type ReadModelStore = S;
fn read_model_store(&self) -> &Self::ReadModelStore {
self
}
}
#[derive(Clone)]
pub struct RepoDependencies<R> {
repo: R,
}
impl<R> RepoDependencies<R> {
pub fn new(repo: R) -> Self {
Self { repo }
}
}
impl<R> HasRepo for RepoDependencies<R> {
type Repo = R;
fn repo(&self) -> &Self::Repo {
&self.repo
}
}
#[derive(Clone)]
pub struct ReadModelStoreDependencies<S> {
read_model_store: S,
}
impl<S> ReadModelStoreDependencies<S> {
pub fn new(read_model_store: S) -> Self {
Self { read_model_store }
}
}
impl<S> HasReadModelStore for ReadModelStoreDependencies<S> {
type ReadModelStore = S;
fn read_model_store(&self) -> &Self::ReadModelStore {
&self.read_model_store
}
}
#[derive(Clone)]
pub struct RepoReadModelDependencies<R, S> {
repo: R,
read_model_store: S,
}
impl<R, S> RepoReadModelDependencies<R, S> {
pub fn new(repo: R, read_model_store: S) -> Self {
Self {
repo,
read_model_store,
}
}
}
impl<R, S> HasRepo for RepoReadModelDependencies<R, S> {
type Repo = R;
fn repo(&self) -> &Self::Repo {
&self.repo
}
}
impl<R, S> HasReadModelStore for RepoReadModelDependencies<R, S> {
type ReadModelStore = S;
fn read_model_store(&self) -> &Self::ReadModelStore {
&self.read_model_store
}
}
#[cfg(test)]
mod tests {
use super::*;
fn assert_has_outbox_store<T: HasOutboxStore>() {}
#[test]
fn has_outbox_store_resolves_through_repo_wrappers() {
assert_has_outbox_store::<crate::HashMapRepository>();
assert_has_outbox_store::<AggregateRepository<crate::HashMapRepository, ()>>();
assert_has_outbox_store::<
AggregateRepository<crate::QueuedRepository<crate::HashMapRepository>, ()>,
>();
}
}