+pub type ActualDbPool = Pool<AsyncPgConnection>;
+
+/// References a pool or connection. Functions must take `&mut DbPool<'_>` to allow implicit reborrowing.
+///
+/// https://github.com/rust-lang/rfcs/issues/1403
+pub enum DbPool<'a> {
+ Pool(&'a ActualDbPool),
+ Conn(&'a mut AsyncPgConnection),
+}
+
+pub enum DbConn<'a> {
+ Pool(PooledConnection<AsyncPgConnection>),
+ Conn(&'a mut AsyncPgConnection),
+}
+
+pub async fn get_conn<'a, 'b: 'a>(pool: &'a mut DbPool<'b>) -> Result<DbConn<'a>, DieselError> {
+ Ok(match pool {
+ DbPool::Pool(pool) => DbConn::Pool(pool.get().await.map_err(|e| QueryBuilderError(e.into()))?),
+ DbPool::Conn(conn) => DbConn::Conn(conn),
+ })
+}
+
+impl<'a> Deref for DbConn<'a> {
+ type Target = AsyncPgConnection;
+
+ fn deref(&self) -> &Self::Target {
+ match self {
+ DbConn::Pool(conn) => conn.deref(),
+ DbConn::Conn(conn) => conn.deref(),
+ }
+ }
+}
+
+impl<'a> DerefMut for DbConn<'a> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ match self {
+ DbConn::Pool(conn) => conn.deref_mut(),
+ DbConn::Conn(conn) => conn.deref_mut(),
+ }
+ }
+}
+
+// Allows functions that take `DbPool<'_>` to be called in a transaction by passing `&mut conn.into()`
+impl<'a> From<&'a mut AsyncPgConnection> for DbPool<'a> {
+ fn from(value: &'a mut AsyncPgConnection) -> Self {
+ DbPool::Conn(value)
+ }
+}
+
+impl<'a, 'b: 'a> From<&'a mut DbConn<'b>> for DbPool<'a> {
+ fn from(value: &'a mut DbConn<'b>) -> Self {
+ DbPool::Conn(value.deref_mut())
+ }
+}