use futures_util::FutureExt;
use crate::{BoxFuture, Pool};
#[derive(Debug)]
pub(crate) enum ConnectionInner<'a, 't: 'a> {
Conn(crate::Conn),
ConnMut(&'a mut crate::Conn),
Tx(&'a mut crate::Transaction<'t>),
}
impl std::ops::Deref for ConnectionInner<'_, '_> {
type Target = crate::Conn;
fn deref(&self) -> &Self::Target {
match self {
ConnectionInner::Conn(ref conn) => conn,
ConnectionInner::ConnMut(conn) => conn,
ConnectionInner::Tx(tx) => tx.0.deref(),
}
}
}
impl std::ops::DerefMut for ConnectionInner<'_, '_> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
ConnectionInner::Conn(conn) => conn,
ConnectionInner::ConnMut(conn) => conn,
ConnectionInner::Tx(tx) => tx.0.inner.deref_mut(),
}
}
}
#[derive(Debug)]
pub struct Connection<'a, 't: 'a> {
pub(crate) inner: ConnectionInner<'a, 't>,
}
impl Connection<'_, '_> {
#[inline]
pub(crate) fn as_mut(&mut self) -> &mut crate::Conn {
&mut self.inner
}
}
impl<'a, 't: 'a> Connection<'a, 't> {
pub fn by_ref(&mut self) -> Connection<'_, '_> {
Connection {
inner: ConnectionInner::ConnMut(self.as_mut()),
}
}
}
impl From<crate::Conn> for Connection<'static, 'static> {
fn from(conn: crate::Conn) -> Self {
Self {
inner: ConnectionInner::Conn(conn),
}
}
}
impl<'a> From<&'a mut crate::Conn> for Connection<'a, 'static> {
fn from(conn: &'a mut crate::Conn) -> Self {
Self {
inner: ConnectionInner::ConnMut(conn),
}
}
}
impl<'a, 't> From<&'a mut crate::Transaction<'t>> for Connection<'a, 't> {
fn from(tx: &'a mut crate::Transaction<'t>) -> Self {
Self {
inner: ConnectionInner::Tx(tx),
}
}
}
impl std::ops::Deref for Connection<'_, '_> {
type Target = crate::Conn;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
pub enum ToConnectionResult<'a, 't: 'a> {
Immediate(Connection<'a, 't>),
Mediate(BoxFuture<'a, Connection<'a, 't>>),
}
impl<'a, 't: 'a> ToConnectionResult<'a, 't> {
#[inline]
pub async fn resolve(self) -> crate::Result<Connection<'a, 't>> {
match self {
ToConnectionResult::Immediate(immediate) => Ok(immediate),
ToConnectionResult::Mediate(mediate) => mediate.await,
}
}
}
pub trait ToConnection<'a, 't: 'a>: Send {
fn to_connection(self) -> ToConnectionResult<'a, 't>;
}
impl<'a, 't: 'a, T: Into<Connection<'a, 't>> + Send> ToConnection<'a, 't> for T {
fn to_connection(self) -> ToConnectionResult<'a, 't> {
ToConnectionResult::Immediate(self.into())
}
}
impl ToConnection<'static, 'static> for Pool {
fn to_connection(self) -> ToConnectionResult<'static, 'static> {
let fut = async move {
let conn = self.get_conn().await?;
Ok(conn.into())
}
.boxed();
ToConnectionResult::Mediate(fut)
}
}
impl<'a> ToConnection<'a, 'static> for &'a Pool {
fn to_connection(self) -> ToConnectionResult<'a, 'static> {
let fut = async move {
let conn = self.get_conn().await?;
Ok(conn.into())
}
.boxed();
ToConnectionResult::Mediate(fut)
}
}