pub trait RequestAuthorizer: Send + Sync {
// Required method
fn authorize<'life0, 'life1, 'async_trait>(
&'life0 self,
request: &'life1 AuthorizationRequest,
) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String)>, ClientError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Async by design (issue #453): real credential providers — an OAuth2
client-credentials token with a refresh-on-expiry cache, for instance —
need to make an HTTP call on a cache miss, which a sync authorize
can’t do without block_on (panics/deadlocks depending on the runtime)
or a pre-fetch-and-stash workaround that reintroduces the expiry race
the cache existed to avoid. #[async_trait] (rather than a bare
async fn in the trait) keeps Arc<dyn RequestAuthorizer> —
CratestackClient::with_request_authorizer stores the authorizer as
a trait object — dyn-compatible; native AFIT would drop that. Same
convention other dyn-dispatched async hook traits already use elsewhere
in the workspace (e.g. cratestack_core::audit::AuditSink).
Target-split (cratestack#1104 follow-up): natively the trait is
Send + Sync with a Send future, exactly as before. On
wasm32-unknown-unknown it is neither, because a browser fetch future
is never Send, so an authorizer that makes a request of its own (the
token refresh above) could not satisfy a Send bound there. An
implementation that builds for both targets uses the same split:
#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] and
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))].
Required Methods§
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".