///|
/// The rest of the chain after a step: the later steps and the transport.
pub type Next = async (Request) -> Response raise RequestoError
///|
/// A link of the chain around the transport. It may change the request,
/// call `next` (or not, or more than once) and change or replace the result.
/// A client's steps run in array order, the first outermost, the same shape
/// as `@http.Middleware`.
pub type Step = async (Request, Next) -> Response raise RequestoError
///|
/// A step that calls `hook` with each request before passing it on.
pub fn on_request(hook : async (Request) -> Unit raise RequestoError) -> Step {
(request, next) => {
hook(request)
next(request)
}
}
///|
/// A step that calls `hook` with each response before returning it.
pub fn on_response(hook : async (Response) -> Unit raise RequestoError) -> Step {
(request, next) => {
let response = next(request)
hook(response)
response
}
}
///|
/// Runs `request` through `steps`, the first outermost, ending at `last`.
async fn run_steps(
steps : Array[Step],
last : Next,
request : Request,
) -> Response raise RequestoError {
let mut next = last
for i = steps.length() - 1; i >= 0; i = i - 1 {
let inner = next
let step = steps[i]
next = request => step(request, inner)
}
next(request)
}