use std::future::{Future, IntoFuture};
use std::marker::PhantomData;
use std::pin::Pin;
use std::time::Duration;
use crate::errors::YdbResultWithCustomerErr;
use crate::TransactionOptions;
use crate::TxMode;
use super::QueryClient;
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
pub struct RetryTxBuilder<'a, F, T> {
client: &'a QueryClient,
callback: F,
options: TransactionOptions,
timeout: Option<Duration>,
idempotent: bool,
_phantom: PhantomData<fn() -> T>,
}
impl<'a, F, T> RetryTxBuilder<'a, F, T> {
pub(crate) fn new(client: &'a QueryClient, callback: F) -> Self {
Self {
client,
callback,
options: TransactionOptions::default(),
timeout: None,
idempotent: false,
_phantom: PhantomData,
}
}
pub fn with_mode(mut self, mode: TxMode) -> Self {
self.options = self.options.with_mode(mode);
self
}
pub fn isolation(self, mode: TxMode) -> Self {
self.with_mode(mode)
}
pub fn with_begin(mut self) -> Self {
self.options = self.options.with_begin();
self
}
pub fn idempotent(mut self, idempotent: bool) -> Self {
self.idempotent = idempotent;
self
}
pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
}
impl<'a, F, T> IntoFuture for RetryTxBuilder<'a, F, T>
where
F: AsyncFnMut(&mut super::Transaction) -> YdbResultWithCustomerErr<T>,
F: 'a,
T: 'a,
{
type Output = YdbResultWithCustomerErr<T>;
type IntoFuture = BoxFuture<'a, Self::Output>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(self.client.run_retry_tx(
self.callback,
self.options,
self.timeout,
self.idempotent,
))
}
}