Skip to content

Instantly share code, notes, and snippets.

@peterstorm
Created March 3, 2022 09:16
Show Gist options
  • Save peterstorm/5e63f8a315a058a763ea0e4cccfe7a8b to your computer and use it in GitHub Desktop.
Save peterstorm/5e63f8a315a058a763ea0e4cccfe7a8b to your computer and use it in GitHub Desktop.
PrototypeDSL
object GeneratorDSL {
final abstract class NotSignedUp
final abstract class SignedUp
final abstract class AgreementCreated
final abstract class AgreementTerminated
sealed trait ActiveEvent
object ActiveEvent {
case object PaymentCreated extends ActiveEvent
case object DunningStarted extends ActiveEvent
}
sealed trait Event[+Before, After]
object Event {
case object SignUp extends Event[NotSignedUp, SignedUp]
case object CreateAgreement extends Event[SignedUp, AgreementCreated]
case object CreatePayment extends Event[AgreementCreated with ActiveEvent, ActiveEvent]
case object TerminateAgreement extends Event[AgreementCreated with ActiveEvent, AgreementTerminated]
case class ChainEvents[A, B, C](
event1: Event[A, B],
event2: Event[B, C]
) extends Event[A, C]
}
implicit class ComposeEvents[A, B](event1: Event[A, B]) {
def ~>[C](event2: Event[B, C]): Event[A, C] =
Event.ChainEvents(event1, event2)
}
val signup: Event[NotSignedUp, SignedUp] = Event.SignUp
val createAgreement: Event[SignedUp, AgreementCreated] = Event.CreateAgreement
val createPayment: Event[AgreementCreated with ActiveEvent, ActiveEvent] = Event.CreatePayment
val terminateAgreeement: Event[AgreementCreated with ActiveEvent, AgreementTerminated] = Event.TerminateAgreement
def parseEvent(event: Event[_, _]): String = {
event match {
case Event.SignUp => "Customer signed up"
case Event.CreateAgreement => "Customer created agreement"
case Event.CreatePayment => "System created payment"
case Event.TerminateAgreement => "Customer terminated agreement"
case Event.ChainEvents(e1, e2) => parseEvent(e1) ++ s"and ${parseEvent(e2)}"
}
}
def customerWithAgreementAndTwoPaymentsActive: Event[NotSignedUp, ActiveEvent] =
signup ~> createAgreement ~> createPayment ~> createPayment
def customerCreatedAndTerminated: Event[NotSignedUp, AgreementTerminated] =
signup ~> createAgreement ~> terminateAgreeement
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment