
Handler.pudu
Pudu49 lines2.1 KB
1/** @HttpClient.Handler.Module — delegating handlers composed around a primary handler */2module PuduLangHttpClient.Handler34import Std.Concurrent.Cancel as Cancel5import PuduLangHttpClient as HttpClient6import PuduLangHttpClient.Request as Request7import PuduLangHttpClient.Response as Response89/** @HttpClient.Handler.Send — sends a request and answers its response; the primary handler's shape */10export type Send = fn(Request.Request, Cancel.Token) -> HttpClient.Outcome[Response.Response]1112/** @HttpClient.Handler.Handler — one layer: sees the request, may call the rest, sees the outcome */13export type Handler = fn(Request.Request, Cancel.Token, Send) -> HttpClient.Outcome[Response.Response]14151617export fn compose(handlers: &Array[Handler], primary: Send) -> Send {18 var inner = primary19 var index = handlers.length() - 120 while index >= 0 {21 inner = around(handlers[index], inner)22 index = index - 123 }24 inner25}262728export fn around(handler: Handler, inner: Send) -> Send {29 fn(request: Request.Request, token: Cancel.Token) -> HttpClient.Outcome[Response.Response] { handler(request, token, inner) }30}313233export fn before(step: fn(Request.Request) -> Request.Request) -> Handler {34 fn(request: Request.Request, token: Cancel.Token, next: Send) -> HttpClient.Outcome[Response.Response] { next(step(request), token) }35}363738export fn after(step: fn(Response.Response) -> Response.Response) -> Handler {39 fn(request: Request.Request, token: Cancel.Token, next: Send) -> HttpClient.Outcome[Response.Response] {40 let response = next(request, token) ?41 Ok(step(response))42 }43}444546export fn passThrough() -> Handler {47 fn(request: Request.Request, token: Cancel.Token, next: Send) -> HttpClient.Outcome[Response.Response] { next(request, token) }48}49