Struct rsasl::callback::Request

source ·
#[repr(transparent)]
pub struct Request<'a>(_);
Expand description

A type-erased request for the value or action defined by Property

Requests can be either a ‘Satisfiable’ request for a value, in which case the methods satisfy and satisfy_with can be used.

Alternatively they may be an ‘Actionable’ request, in which case get_action returns an associated value.

Whether a request is ‘Actionable’ or ‘Satisfiable’ depends on the property, mechanism and side and is documented in the documentation of the mechanism implementation in question.

Implementations

Returns true iff this Request is for the Property P.

Using this method is generally not necessary as satisfy, satisfy_with and get_action can used efficiently without.

Get a reference to the associated value of an ‘Actionable’ Request for P.

This method does not work for all requests, even if Self::is returned true for the given P, as ‘Satisfiable’ requests are instead requesting a value for P.

get_action will return None if the request is not an Actionable request for the given P, or if called for the same P multiple times.

// Since get_action returns `None` if P doesn't match, `if let` constructs are a nice way
// to check for the different options
if let Some(url) = request.get_action::<OpenID20AuthenticateInBrowser>() {
    do_something(url);
    return Ok(());
}
if let Some(url) = request.get_action::<Saml20AuthenticateInBrowser>() {
    do_something_else(url);
    return Ok(());
}
Ok(())

Satisfy a ‘Satisfiable’ request using the provided value.

If the type of the request is P and the request was not yet satisfied, this method will satisfy the request and return an opaque Err that must be bubbled up.

If the request is not for the property P, already satisfied or not a ‘Satisfiable’ request this method will always return Ok(&mut Self).

This behaviour allows to easily chain multiple calls using the ? operator:

request
    .satisfy::<AuthId>("authid")? // if `P` is AuthId this will immediately return
    .satisfy::<Password>(b"password")?
    // It's important that errors are returned so the last call should have a `?` too.
    .satisfy::<AuthzId>("authzid")?;
faulty use of satisfy/satisfy_with

It’s important to note that calls will succeed if the request is not for this property. Thus care must be taken when satisfying requests to prevent bugs:

if let Some(password) = self.try_get_cached_password() {
    request.satisfy::<Password>(password)?;
    // This is wrong, as the above call will *succeed* if `AuthId` was requested but this
    // return may prevent the `satisfy` below from ever being evaluated.
    return Ok(());
} else {
    let password = self.ask_user_for_password()?;
    request.satisfy::<Password>(password)?;
}
request.satisfy::<AuthId>("foobar")?;

If generating the value is expensive or requires interactivity using the method satisfy_with may be preferable.

Satisfy a ‘Satisfiable’ request using the provided closure.

If the type of the request is P and the request was not yet satisfied, this method will evaluate the closure and satisfy the request, returning an opaque Err that must be bubbled up.

If the request is not for the property P, already satisfied or not a ‘Satisfiable’ request this method will is guaranteed to not evaluate the provided closure and return an Ok(&mut Self).

This behaviour allows to easily chain multiple calls using the ? operator:

// Skipping the interactive asking if the password was cached previously
if let Some(password) = try_get_cached_password() {
    // Several calls for satisfy may exist, but only the first value set will ever be used.
    request.satisfy::<Password>(password)?;
}

request
    .satisfy::<AuthId>(ask_user_for_authid()?)?
    .satisfy::<Password>(ask_user_for_password()?)?;
faulty use of satisfy/satisfy_with

It’s important to note that calls will succeed if the request is not for this property. Thus care must be taken when satisfying requests to prevent bugs:

if let Some(password) = try_get_cached_password() {
    request.satisfy::<Password>(password)?;
    // This is wrong, as the above call will *succeed* if `AuthId` was requested but this
    // return may prevent the `satisfy` below from ever being evaluated.
    return Ok(());
} else {
    let password = ask_user_for_password()?;
    request.satisfy::<Password>(password)?;
}
request.satisfy::<AuthId>("foobar")?;

If the value for a property is static or readily available using satisfy may be preferable.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more