use std::fmt::Debug;
use anyhow::Result;
use async_trait::async_trait;
use tonic::transport::Channel;
use crate::api::dgraph_client::DgraphClient as DClient;
use crate::client::DgraphClient;
#[async_trait]
pub trait ILazyChannel: Sync + Send + Debug + Clone {
async fn channel(&mut self) -> Result<Channel>;
}
#[async_trait]
pub trait ILazyClient: Sync + Send + Debug + Clone {
type Channel: ILazyChannel;
async fn client(&mut self) -> Result<&mut DgraphClient>;
fn channel(self) -> Self::Channel;
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct LazyClient<C: ILazyChannel> {
channel: C,
client: Option<DgraphClient>,
}
impl<C: ILazyChannel> LazyClient<C> {
pub fn new(channel: C) -> Self {
Self {
channel,
client: None,
}
}
async fn init(&mut self) -> Result<()> {
if self.client.is_none() {
let client = DgraphClient::Default {
client: DClient::new(self.channel.channel().await?),
};
self.client.replace(client);
}
Ok(())
}
}
#[async_trait]
impl<C: ILazyChannel> ILazyClient for LazyClient<C> {
type Channel = C;
async fn client(&mut self) -> Result<&mut DgraphClient> {
self.init().await?;
if let Some(client) = &mut self.client {
Ok(client)
} else {
unreachable!()
}
}
fn channel(self) -> Self::Channel {
self.channel
}
}