diff --git a/src/main/kotlin/com/cultureamp/eventsourcing/Configuration.kt b/src/main/kotlin/com/cultureamp/eventsourcing/Configuration.kt index 8f790bb..7939a15 100644 --- a/src/main/kotlin/com/cultureamp/eventsourcing/Configuration.kt +++ b/src/main/kotlin/com/cultureamp/eventsourcing/Configuration.kt @@ -13,6 +13,12 @@ data class Configuration Agg, val aggregateType: Agg.() -> String ) { + object Builder { + inline fun create(noinline create: (CreationCmd) -> Either): CreateBuilder { + return CreateBuilder(CreationCmd::class, create) + } + } + companion object { inline fun from( @@ -92,4 +98,44 @@ data class Configuration): Agg = updateEvents.fold(initial) { aggregate, updateEvent -> updated(aggregate, updateEvent) } +} + + +class CreateBuilder( + val creationCommandClass: KClass, + val create: (CreationCmd) -> Either +) { + inline fun update(noinline update: Agg.(UpdateCmd) -> Either>) = UpdateBuilder(creationCommandClass, UpdateCmd::class, create, update) +} + +class UpdateBuilder( + private val creationCommandClass: KClass, + private val updateCommandClass: KClass, + private val create: (CreationCmd) -> Either, + private val update: Agg.(UpdateCmd) -> Either> +) { + fun created(created: (CreationEvt) -> Agg) = CreatedBuilder(creationCommandClass, updateCommandClass, create, update, created) + fun buildStateless(instance: Agg, aggregateType: Agg.() -> String = { this::class.simpleName!! }) = UpdatedBuilder(creationCommandClass, updateCommandClass, create, update, { instance }, { instance }).build(aggregateType) +} + +class CreatedBuilder( + private val creationCommandClass: KClass, + private val updateCommandClass: KClass, + private val create: (CreationCmd) -> Either, + private val update: Agg.(UpdateCmd) -> Either>, + private val created: (CreationEvt) -> Agg) { + fun updated(updated: Agg.(UpdateEvt) -> Agg) = UpdatedBuilder(creationCommandClass, updateCommandClass, create, update, created, updated) + fun build() = UpdatedBuilder(creationCommandClass, updateCommandClass, create, update, created, { _ -> this }).build() +} + +class UpdatedBuilder( + private val creationCommandClass: KClass, + private val updateCommandClass: KClass, + private val create: (CreationCmd) -> Either, + private val update: Agg.(UpdateCmd) -> Either>, + private val created: (CreationEvt) -> Agg, + private val updated: Agg.(UpdateEvt) -> Agg +) { + fun build(aggregateType: Agg.() -> String = { this::class.simpleName!! }) = Configuration(creationCommandClass, updateCommandClass, create, update, created, updated, aggregateType) + } \ No newline at end of file