Skip to content

Commit

Permalink
Add DSL/Builder to make the API/compiler errors easier to understand
Browse files Browse the repository at this point in the history
Changes an error that looks like this:
```
Error:(28, 27) Kotlin: Type inference failed: Cannot infer type parameter UpdateEvt in inline fun <reified CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError, reified UpdateCmd : UpdateCommand, UpdateEvt : UpdateEvent, reified Agg : Aggregate> from(noinline create: (CreationCmd) -> Either<CmdErr, CreationEvt>, noinline update: Agg.(UpdateCmd) -> Either<CmdErr, List<UpdateEvt>>, noinline created: (CreationEvt) -> Agg, noinline updated: Agg.(UpdateEvt) -> Agg = ..., noinline aggregateType: Agg.() -> String = ...): Configuration<CreationCmd, CreationEvt, CmdErr, UpdateCmd, UpdateEvt, Agg>
None of the following substitutions
((PizzaCreationCommand) -> Either<PizzaError, PizzaCreated>,Aggregate.(PizzaUpdateCommand) -> Either<PizzaError, List<PizzaUpdateEvent>>,(PizzaCreated) -> Aggregate,Aggregate.(PizzaUpdateEvent) -> Aggregate,Aggregate.() -> String)
((PizzaCreationCommand) -> Either<PizzaError, PizzaCreated>,Aggregate.(PizzaUpdateCommand) -> Either<PizzaError, List<UpdateEvent>>,(PizzaCreated) -> Aggregate,Aggregate.(UpdateEvent) -> Aggregate,Aggregate.() -> String)
((PizzaCreationCommand) -> Either<PizzaError, PizzaCreated>,Aggregate.(PizzaUpdateCommand) -> Either<PizzaError, List<@ParameterName PizzaUpdateCommand>>,(PizzaCreated) -> Aggregate,Aggregate.(PizzaUpdateCommand) -> Aggregate,Aggregate.() -> String)
can be applied to
(KFunction1<@ParameterName PizzaCreationCommand, Either<PizzaError, PizzaCreated>>,KFunction2<PizzaAggregate, @ParameterName PizzaUpdateCommand, Either<PizzaError, List<PizzaUpdateEvent>>>,KFunction1<@ParameterName PizzaCreationEvent, PizzaAggregate>,KFunction2<PizzaAggregate, @ParameterName PizzaUpdateCommand, Either<PizzaError, List<PizzaUpdateEvent>>>)
```
into

```
Error:(26, 30) Kotlin: Type mismatch: inferred type is KFunction2<PizzaAggregate, @ParameterName PizzaUpdateCommand, Either<PizzaError, List<PizzaUpdateEvent>>> but PizzaAggregate.(PizzaUpdateEvent) -> PizzaAggregate was expected
```
  • Loading branch information
williamboxhall committed Apr 20, 2020
1 parent cac6ce0 commit 89c1dbe
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/main/kotlin/com/cultureamp/eventsourcing/Configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ data class Configuration<CreationCmd : CreationCommand, CreationEvt : CreationEv
val updated: Agg.(UpdateEvt) -> Agg,
val aggregateType: Agg.() -> String
) {
object Builder {
inline fun <reified CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError>create(noinline create: (CreationCmd) -> Either<CmdErr, CreationEvt>): CreateBuilder<CreationCmd, CreationEvt, CmdErr> {
return CreateBuilder(CreationCmd::class, create)
}
}

companion object {

inline fun <reified CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError, reified UpdateCmd : UpdateCommand, UpdateEvt : UpdateEvent, reified Agg : Aggregate> from(
Expand Down Expand Up @@ -92,4 +98,44 @@ data class Configuration<CreationCmd : CreationCommand, CreationEvt : CreationEv

private fun updated(initial: Agg, updateEvents: List<UpdateEvt>): Agg =
updateEvents.fold(initial) { aggregate, updateEvent -> updated(aggregate, updateEvent) }
}


class CreateBuilder<CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError>(
val creationCommandClass: KClass<CreationCmd>,
val create: (CreationCmd) -> Either<CmdErr, CreationEvt>
) {
inline fun <Agg : Aggregate, reified UpdateCmd : UpdateCommand, UpdateEvt : UpdateEvent> update(noinline update: Agg.(UpdateCmd) -> Either<CmdErr, List<UpdateEvt>>) = UpdateBuilder(creationCommandClass, UpdateCmd::class, create, update)
}

class UpdateBuilder<CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError, UpdateCmd : UpdateCommand, UpdateEvt : UpdateEvent, Agg : Aggregate>(
private val creationCommandClass: KClass<CreationCmd>,
private val updateCommandClass: KClass<UpdateCmd>,
private val create: (CreationCmd) -> Either<CmdErr, CreationEvt>,
private val update: Agg.(UpdateCmd) -> Either<CmdErr, List<UpdateEvt>>
) {
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<CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError, UpdateCmd : UpdateCommand, UpdateEvt : UpdateEvent, Agg : Aggregate>(
private val creationCommandClass: KClass<CreationCmd>,
private val updateCommandClass: KClass<UpdateCmd>,
private val create: (CreationCmd) -> Either<CmdErr, CreationEvt>,
private val update: Agg.(UpdateCmd) -> Either<CmdErr, List<UpdateEvt>>,
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<CreationCmd : CreationCommand, CreationEvt : CreationEvent, CmdErr : CommandError, UpdateCmd : UpdateCommand, UpdateEvt : UpdateEvent, Agg : Aggregate>(
private val creationCommandClass: KClass<CreationCmd>,
private val updateCommandClass: KClass<UpdateCmd>,
private val create: (CreationCmd) -> Either<CmdErr, CreationEvt>,
private val update: Agg.(UpdateCmd) -> Either<CmdErr, List<UpdateEvt>>,
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)

}

0 comments on commit 89c1dbe

Please sign in to comment.