Trait ldap3::adapters::Adapter[][src]

pub trait Adapter<'a, S>: AdapterClone<'a, S> + Debug + Send + Sync + 'a {
#[must_use]    fn start<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 mut self,
        stream: &'life1 mut SearchStream<'a, S>,
        base: &'life2 str,
        scope: Scope,
        filter: &'life3 str,
        attrs: Vec<S>
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
    where
        'a: 'async_trait,
        'life0: 'async_trait,
        'life1: 'async_trait,
        'life2: 'async_trait,
        'life3: 'async_trait,
        Self: 'async_trait
;
#[must_use] fn next<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        stream: &'life1 mut SearchStream<'a, S>
    ) -> Pin<Box<dyn Future<Output = Result<Option<ResultEntry>>> + Send + 'async_trait>>
    where
        'a: 'async_trait,
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
;
#[must_use] fn finish<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        stream: &'life1 mut SearchStream<'a, S>
    ) -> Pin<Box<dyn Future<Output = LdapResult> + Send + 'async_trait>>
    where
        'a: 'async_trait,
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
; }

Adapter interface to a Search.

Structs implementing this trait:

  • Must additionally implement Clone and Debug;

  • Must be Send and Sync.

The trait is parametrized with 'a, the lifetime bound propagated to trait objects, and S, which is used in the start() method as the generic type for the attribute name vector. (It must appear here because of object safety.) When implementing the trait, S must be constrained to AsRef<str> + Send + Sync + 'a. To use a bare instance of a struct implementing this trait in the call to streaming_search_with(), the struct must also implement SoloMarker.

There are three points where an adapter can hook into a Search:

  1. Initialization, which can be used to capture the parameters of the operation itself and the underlying Ldap handle, as well as to prepare the internal adapter state. This is done in the start() method.

  2. Entry iteration, where each fetched entry can be examined, transformed, or discarded. The next() method serves this purpose.

  3. Termination, which can examine and transform the result, or invoke further operations to terminate other active connections or operations, if necessary. The finish() method is used for this.

All three methods are called in an async context, so they are marked as async and implemented using the async_trait proc macro from the async-trait crate. To make chaining work, all trait methods must call the corresponding method on the passed stream handle.

Additional details of the calling structure are provided in the documentation of the StreamState enum.

Example: the EntriesOnly adapter

This adapter discards intermediate messages and collects all referreals in the result of the Search operation. The (slightly simplified) source is annotated by comments pointing out the notable details of the implementation.

// An adapter must implement Clone and Debug
//
// The slightly awkward Option-wrapping lets us move the vector
// out of the struct in finish()
#[derive(Clone, Debug)]
pub struct EntriesOnly {
    refs: Option<Vec<String>>,
}

// This impl enables the use of a bare struct instance
// when invoking a Search
impl SoloMarker for EntriesOnly {}

// Adapter impl must be derived with the async_trait proc macro
// until Rust supports async fns in traits directly
#[async_trait]
impl<'a, S> Adapter<'a, S> for EntriesOnly
where
    // The S generic parameter must have these bounds
    S: AsRef<str> + Send + Sync + 'a,
{
    // The start() method doesn't do much
    async fn start(
        &mut self,
        stream: &mut SearchStream<'a, S>,
        base: &str,
        scope: Scope,
        filter: &str,
        attrs: Vec<S>,
    ) -> Result<()> {
        self.refs.as_mut().expect("refs").clear();
        // Call up the adapter chain
        stream.start(base, scope, filter, attrs).await
    }

    // Multiple calls up the chain are possible before
    // a single result entry is returned
    async fn next(
        &mut self,
        stream: &mut SearchStream<'a, S>
    ) -> Result<Option<ResultEntry>> {
        loop {
            // Call up the adapter chain
            return match stream.next().await {
                Ok(None) => Ok(None),
                Ok(Some(re)) => {
                    if re.is_intermediate() {
                        continue;
                    } else if re.is_ref() {
                        self.refs.as_mut().expect("refs").extend(parse_refs(re.0));
                        continue;
                    } else {
                        Ok(Some(re))
                    }
                }
                Err(e) => Err(e),
            };
        }
    }

    // The result returned from the upcall is modified by our values
    async fn finish(&mut self, stream: &mut SearchStream<'a, S>) -> LdapResult {
        // Call up the adapter chain
        let mut res = stream.finish().await;
        res.refs.extend(self.refs.take().expect("refs"));
        res
    }
}

Required methods

#[must_use]fn start<'life0, 'life1, 'life2, 'life3, 'async_trait>(
    &'life0 mut self,
    stream: &'life1 mut SearchStream<'a, S>,
    base: &'life2 str,
    scope: Scope,
    filter: &'life3 str,
    attrs: Vec<S>
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>> where
    'a: 'async_trait,
    'life0: 'async_trait,
    'life1: 'async_trait,
    'life2: 'async_trait,
    'life3: 'async_trait,
    Self: 'async_trait, 
[src]

Initialize the stream.

#[must_use]fn next<'life0, 'life1, 'async_trait>(
    &'life0 mut self,
    stream: &'life1 mut SearchStream<'a, S>
) -> Pin<Box<dyn Future<Output = Result<Option<ResultEntry>>> + Send + 'async_trait>> where
    'a: 'async_trait,
    'life0: 'async_trait,
    'life1: 'async_trait,
    Self: 'async_trait, 
[src]

Fetch the next entry from the stream.

#[must_use]fn finish<'life0, 'life1, 'async_trait>(
    &'life0 mut self,
    stream: &'life1 mut SearchStream<'a, S>
) -> Pin<Box<dyn Future<Output = LdapResult> + Send + 'async_trait>> where
    'a: 'async_trait,
    'life0: 'async_trait,
    'life1: 'async_trait,
    Self: 'async_trait, 
[src]

Return the result from the stream.

Loading content...

Implementors

impl<'a, S> Adapter<'a, S> for EntriesOnly where
    S: AsRef<str> + Send + Sync + 'a, 
[src]

impl<'a, S> Adapter<'a, S> for PagedResults<S> where
    S: AsRef<str> + Clone + Debug + Send + Sync + 'a, 
[src]

Loading content...