use anyhow::Result;
use async_trait::async_trait;
use crate::client::acl::LazyAclClient;
use crate::client::lazy::ILazyChannel;
#[cfg(feature = "tls")]
use crate::client::tls::LazyTlsChannel;
use crate::client::{AclClientType as AsyncAclClient, IClient as IAsyncClient, LazyChannel};
use crate::sync::client::{ClientVariant, IClient};
use crate::sync::txn::TxnType as SyncTxn;
use crate::sync::{TxnBestEffortType, TxnMutatedType, TxnReadOnlyType};
use crate::txn::TxnType;
#[derive(Debug)]
#[doc(hidden)]
pub struct Acl<C: ILazyChannel> {
async_client: AsyncAclClient<C>,
}
#[async_trait]
impl<C: ILazyChannel> IClient for Acl<C> {
type AsyncClient = AsyncAclClient<C>;
type Client = LazyAclClient<Self::Channel>;
type Channel = C;
fn client(&self) -> Self::Client {
self.async_client.extra.client()
}
fn clients(self) -> Vec<Self::Client> {
self.async_client.extra.clients()
}
fn async_client_ref(&self) -> &Self::AsyncClient {
&self.async_client
}
fn async_client(self) -> Self::AsyncClient {
self.async_client
}
fn new_txn(&self) -> TxnType<Self::Client> {
self.async_client_ref().new_txn()
}
async fn login<T: Into<String> + Send + Sync>(
self,
_user_id: T,
_password: T,
) -> Result<AsyncAclClient<Self::Channel>> {
Ok(self.async_client)
}
#[cfg(feature = "dgraph-21-03")]
async fn login_into_namespace<T: Into<String> + Send + Sync>(
self,
_user_id: T,
_password: T,
_namespace: u64,
) -> Result<AsyncAclClient<Self::Channel>> {
Ok(self.async_client)
}
}
pub type AclClientType<C> = ClientVariant<Acl<C>>;
pub type AclClient = AclClientType<LazyAclClient<LazyChannel>>;
#[cfg(feature = "tls")]
pub type AclTlsClient = AclClientType<LazyAclClient<LazyTlsChannel>>;
pub type TxnAcl = SyncTxn<LazyAclClient<LazyChannel>>;
pub type TxnAlcReadOnly = TxnReadOnlyType<LazyAclClient<LazyChannel>>;
pub type TxnAclBestEffort = TxnBestEffortType<LazyAclClient<LazyChannel>>;
pub type TxnAclMutated = TxnMutatedType<LazyAclClient<LazyChannel>>;
#[cfg(feature = "tls")]
pub type TxnAclTls = SyncTxn<LazyAclClient<LazyTlsChannel>>;
#[cfg(feature = "tls")]
pub type TxnAclTlsReadOnly = TxnReadOnlyType<LazyAclClient<LazyTlsChannel>>;
#[cfg(feature = "tls")]
pub type TxnAclTlsBestEffort = TxnBestEffortType<LazyAclClient<LazyTlsChannel>>;
#[cfg(feature = "tls")]
pub type TxnAclTlsMutated = TxnMutatedType<LazyAclClient<LazyTlsChannel>>;
impl<S: IClient> ClientVariant<S> {
pub fn login<T: Into<String> + Send + Sync>(
self,
user_id: T,
password: T,
) -> Result<AclClientType<S::Channel>> {
let async_client = {
let client = self.extra;
self.state
.rt
.block_on(async move { client.login(user_id, password).await })?
};
Ok(AclClientType {
state: self.state,
extra: Acl { async_client },
})
}
#[cfg(feature = "dgraph-21-03")]
pub fn login_into_namespace<T: Into<String> + Send + Sync>(
self,
user_id: T,
password: T,
namespace: u64,
) -> Result<AclClientType<S::Channel>> {
let async_client = {
let client = self.extra;
self.state.rt.block_on(async move {
client
.login_into_namespace(user_id, password, namespace)
.await
})?
};
Ok(AclClientType {
state: self.state,
extra: Acl { async_client },
})
}
}
impl<C: ILazyChannel> AclClientType<C> {
pub fn refresh_login(&self) -> Result<()> {
self.state
.rt
.block_on(async { self.extra.async_client.refresh_login().await })
}
}
#[cfg(test)]
mod tests {
use crate::sync::Client;
#[test]
fn login() {
let client = Client::new("http://127.0.0.1:19080")
.unwrap()
.login("groot", "password");
if let Err(err) = &client {
dbg!(err);
}
assert!(client.is_ok());
}
#[test]
#[cfg(feature = "dgraph-21-03")]
fn login_into_namespace() {
let client = Client::new("http://127.0.0.1:19080")
.unwrap()
.login_into_namespace("groot", "password", 0);
if let Err(err) = &client {
dbg!(err);
}
assert!(client.is_ok());
}
#[test]
fn refresh_login() {
let client = Client::new("http://127.0.0.1:19080")
.unwrap()
.login("groot", "password")
.expect("logged");
let refresh = client.refresh_login();
assert!(refresh.is_ok());
}
}