title: Is there a higher-level way to write a custom GraphStage?
body: <p>I'm trying to understand some of the newer bits of Akka Streams.  I have a custom FanOutShape2 shape that does something very simple:  take an input of (Boolean, Option[A_Thing]) and decide wether to route flow to either out0 or out1 (pass or fail) like this:</p>
  
  <pre><code>object PassFilter {
    type FilterShape = FanOutShape2[(Boolean, Option[OutputWrapper]), OutputWrapper, akka.NotUsed]
  }
  import PassFilter._
  
  case class PassFilter()(implicit asys: ActorSystem) extends GraphStage[FilterShape] {
    val mergedIn: Inlet[(Boolean, Option[OutputWrapper])] = Inlet("Merged")
    val outPass: Outlet[OutputWrapper] = Outlet("Pass")
    val outFail: Outlet[akka.NotUsed] = Outlet("Fail")
  
    override val shape: FilterShape = new FanOutShape2(mergedIn, outPass, outFail)
  
    override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) {
      override def preStart(): Unit = pull(mergedIn)
      setHandler(mergedIn, new InHandler {
        override def onPush(): Unit = {
          val (passedPrivacy, outWrapper) = grab(mergedIn)
          if (!passedPrivacy || outWrapper.isEmpty)
            push(outFail, akka.NotUsed)
          else
            push(outPass, outWrapper.get)
          pull(mergedIn)
        }
        override def onUpstreamFinish(): Unit = {} // necessary for some reason!
      })
      setHandler(outPass, eagerTerminateOutput)
      setHandler(outFail, eagerTerminateOutput)
    }
  }
  </code></pre>
  
  <p>This basic idea works, and I can see it gives me the possibility of total control of the process, but for this super-trivial decision logic is there a simpler, higher-level way to create a "widget" that can be included in my GraphDSL?</p>