Skip to content

Instantly share code, notes, and snippets.

@ankurcha
Created July 24, 2015 23:35
Show Gist options
  • Select an option

  • Save ankurcha/624a4cf929913cd6891b to your computer and use it in GitHub Desktop.

Select an option

Save ankurcha/624a4cf929913cd6891b to your computer and use it in GitHub Desktop.
Function to convert a stream of events into the "state" of the stream. The presence of a Bad event determines if it is errored before play request or after.
// events
trait Event
sealed abstract class BadEvent() extends Event
sealed abstract class GoodEvent() extends Event
sealed case class Ping() extends GoodEvent
sealed case class PlayRequest() extends GoodEvent
sealed case class Buffer() extends BadEvent
// stream states
trait StreamState
sealed class OK() extends StreamState
sealed class Error() extends StreamState
sealed case class Success() extends OK
sealed case class Failure() extends Error
sealed case class OKBeforePlayRequest() extends OK
sealed case class ErrorBeforePlayRequest() extends Error
sealed case class ErrorAfterPlayRequest() extends Error
// stream of events to state
def toStreamState(stream: Seq[Event], startState: StreamState = Success()): StreamState = {
stream.foldLeft(startState)((head: StreamState, current: Event) => {
(head, current) match {
case (_: OKBeforePlayRequest, y: Event) =>
y match {
case _: PlayRequest => OKBeforePlayRequest()
case _: GoodEvent => Success()
case _: BadEvent => ErrorAfterPlayRequest()
}
case (_: ErrorAfterPlayRequest, _: Event) => ErrorAfterPlayRequest()
case (_: ErrorBeforePlayRequest, _: Event) => ErrorBeforePlayRequest()
case (_: OK, y: Event) =>
y match {
case _: PlayRequest => OKBeforePlayRequest()
case _: GoodEvent => Success()
case _: BadEvent => Failure()
}
case (_: Error, y: Event) =>
y match {
case _: PlayRequest => ErrorBeforePlayRequest()
case _: GoodEvent => Success()
case _: BadEvent => Failure()
}
}
})
}
// test
def test() = {
val stream1 = Seq( Ping(), Ping(), PlayRequest(), Ping(), Ping() ) // success
val stream2 = Seq( Ping(), Ping(), PlayRequest(), Buffer(), Ping() ) // error after play
val stream3 = Seq( Ping(), Buffer(), PlayRequest(), Ping(), Ping() ) // error before play
val r1 = toStreamState(stream = stream1)
val r2 = toStreamState(stream = stream2)
val r3 = toStreamState(stream = stream3)
Seq(r1, r2, r3)
}
// run test
test()
@ankurcha
Copy link
Author

Version 2 (much cleaner):

  // stream of events to state
  def toStreamState(stream: Seq[Event], start: StreamState = Success()): StreamState =
    stream.foldLeft(start) {
      case (_: OKBeforePlayRequest, _: BadEvent)  => ErrorAfterPlayRequest()
      case (_: OK, _: PlayRequest)                => OKBeforePlayRequest()
      case (_: Error, _: PlayRequest)             => ErrorBeforePlayRequest()
      case (_: OKBeforePlayRequest, _: GoodEvent) => Success()

      case (_: ErrorAfterPlayRequest, _)          => ErrorAfterPlayRequest()
      case (_: ErrorBeforePlayRequest, _)         => ErrorBeforePlayRequest()

      case (_, _: GoodEvent)                      => Success()
      case (_, _: BadEvent)                       => Failure()
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment