Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion progenitor-impl/src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ impl Generator {
};
let pre_hook = self.settings.pre_hook.as_ref().map(|hook| {
quote! {
(#hook)(#inner &#request_ident);
(#hook)(#inner &mut #request_ident);
}
});
let pre_hook_async = self.settings.pre_hook_async.as_ref().map(|hook| {
Expand Down
7 changes: 4 additions & 3 deletions progenitor-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,10 @@ impl syn::parse::Parse for SpecSource {
/// The optional `pre_hook` is either a closure (that must be within
/// parentheses: `(fn |[inner,] request| { .. })`) or a path to a function. The
/// closure or function must take one or two parameters: the inner type (if one
/// is specified) and a `&reqwest::Request`. This allows clients to examine
/// requests before they're sent to the server, for example to log them. The
/// optional `pre_hook_async` is the `async` variant of the same.
/// is specified) and a `&mut reqwest::Request`. This allows clients to examine
/// or modify requests before they're sent to the server, for example to log
/// them or add a header. The optional `pre_hook_async` is the `async` variant
/// of the same.
///
/// The optional `post_hook` is either a closure (that must be within
/// parentheses: `(fn |[inner,] result| { .. })`) or a path to a function. The
Expand Down
33 changes: 33 additions & 0 deletions progenitor/tests/build_hooks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2026 Oxide Computer Company

//! Validate the signatures with which pre and post hooks are invoked.

fn add_header(req: &mut reqwest::Request) {
req.headers_mut().insert(
"x-pre-hook",
reqwest::header::HeaderValue::from_static("present"),
);
}

fn observe(_req: &reqwest::Request) {}

fn observe_result(_result: &Result<reqwest::Response, reqwest::Error>) {}

// The sync pre_hook receives `&mut reqwest::Request` so that it can modify
// the request before it's sent.
mod pre_hook_mut {
progenitor::generate_api!(
spec = "../sample_openapi/keeper.json",
pre_hook = crate::add_header,
post_hook = crate::observe_result,
);
}

// A pre_hook written against `&reqwest::Request` must continue to compile:
// the generated call site passes `&mut request`, which coerces to `&_`.
mod pre_hook_ref {
progenitor::generate_api!(
spec = "../sample_openapi/keeper.json",
pre_hook = crate::observe,
);
}
Loading