///|
/// Circuit-breaker middleware (← go-zero's `breaker` interceptor): gate each
/// HTTP request through a shared `Breaker`. An admitted request's outbound
/// `HttpResponseStart` status is observed — a `5xx` settles its promise as a
/// failure, anything else as a success, and that is what feeds the window. A
/// shed request is answered `503 Service Unavailable` without the wrapped app
/// running. Non-HTTP scopes pass through untouched.
///
/// The promise starts out a failure and only the observed status makes it a
/// success, on a `defer` — the same shape go-zero's `doReq` uses, so a handler
/// that raises or is cancelled before answering counts against the window
/// instead of quietly not counting at all.
pub fn breaker(
  b : @breaker.Breaker,
  refusal~ : Refusal = unavailable,
) -> Middleware {
  inner => {
    (scope, receive, send) => {
      match scope {
        Http(_) =>
          match b.allow() {
            Some(p) => {
              let status : Ref[Int32] = { val: 500, }
              let observed : @moonasgi.Send = event => {
                match event {
                  HttpResponseStart(status=s, headers~, trailers~) => {
                    status.val = s
                    send(
                      @moonasgi.Event::HttpResponseStart(
                        status=s,
                        headers~,
                        trailers~,
                      ),
                    )
                  }
                  other => send(other)
                }
              }
              defer (if status.val >= 500 { p.reject() } else { p.accept() })
              inner(scope, receive, observed)
            }
            None =>
              for event in refusal.events() {
                send(event)
              }
          }
        _ => inner(scope, receive, send)
      }
    }
  }
}