use ldap3::{Ldap, LdapError, Scope, SearchEntry};
use crate::{ToLdapFilter};
pub async fn search<F: ToLdapFilter>(connection: &mut Ldap, base: &str, scope: Scope, filter: &F, attributes: Vec<&str>) -> Result<Vec<SearchEntry>, LdapError> {
connection
.search(base, scope, &filter.to_ldap_filter(), attributes)
.await
.and_then(|sr| sr.success())
.map(|(res, _)| res.iter().map(|re| SearchEntry::construct(re.clone())).collect::<Vec<SearchEntry>>())
}
pub enum SearchAndConvertError<T> {
LdapError(LdapError),
ConvertError(T)
}
pub async fn search_and_convert<F: ToLdapFilter, E, T: for<'a> TryFrom<&'a SearchEntry, Error=SearchAndConvertError<E>>>(connection: &mut Ldap, base: &str, scope: Scope, filter: &F, attributes: Vec<&str>) -> Result<Vec<T>, SearchAndConvertError<E>> {
search(connection, base, scope, filter, attributes)
.await
.map_err(|e| SearchAndConvertError::LdapError(e))
.and_then(|ses| ses.iter().map(|se| se.try_into()).collect::<Result<Vec<T>, SearchAndConvertError<E>>>())
}