Trait ldap3::adapters::Adapter [−][src]
Adapter interface to a Search.
Structs implementing this trait:
-
Must additionally implement
Clone
andDebug
; -
Must be
Send
andSync
.
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:
-
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 thestart()
method. -
Entry iteration, where each fetched entry can be examined, transformed, or discarded. The
next()
method serves this purpose. -
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]
&'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,
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]
&'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,
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]
&'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,
Return the result from the stream.
Implementors
impl<'a, S> Adapter<'a, S> for EntriesOnly where
S: AsRef<str> + Send + Sync + 'a,
[src]
S: AsRef<str> + Send + Sync + 'a,
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]
&'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,
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]
&'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,
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]
&'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,
impl<'a, S> Adapter<'a, S> for PagedResults<S> where
S: AsRef<str> + Clone + Debug + Send + Sync + 'a,
[src]
S: AsRef<str> + Clone + Debug + Send + Sync + 'a,
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]
&'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,
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]
&'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,
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]
&'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,