cartel-pg 0.20.0

Async PostgreSQL driver for the dope runtime
Documentation
use dope::{core::driver::route::KeyTag, manifold::client::conn};

use crate::{
    port::pool::{key, slot},
    protocol,
};

mod bound;
mod rejected;

pub(crate) use bound::Bound;
pub(crate) use rejected::Rejected;

#[derive(Clone, Copy)]
pub(crate) struct Backend<'a, 'd, const ID: u8> {
    slot: &'a slot::Slot<'d, ID>,
}

impl<'a, 'd, const ID: u8> Backend<'a, 'd, ID> {
    pub(crate) const fn new(slot: &'a slot::Slot<'d, ID>) -> Self {
        Self { slot }
    }

    pub(crate) fn try_install(
        &self,
        token: conn::Id<'d, KeyTag<ID>>,
        key: key::Key,
    ) -> Result<(), protocol::Reason> {
        let slot::Phase::Handshaking(bound) = self.slot.phase.get() else {
            return Err(protocol::Reason::BackendKeyStale);
        };
        if bound.token != token {
            return Err(protocol::Reason::BackendKeyStale);
        }
        if self.slot.pid.get().is_some() {
            return Err(protocol::Reason::DuplicateBackendKey);
        }
        self.slot.pid.set(Some(key.pid()));
        self.slot.key.set(key);
        Ok(())
    }

    pub(crate) fn bind(self, target: conn::Id<'d, KeyTag<ID>>) -> Option<(Bound<'a, 'd, ID>, i32)> {
        let pid = self.pid(target)?;
        Some((
            Bound {
                slot: self.slot,
                target,
            },
            pid,
        ))
    }

    pub(crate) fn pid(&self, token: conn::Id<'d, KeyTag<ID>>) -> Option<i32> {
        let slot::Phase::Ready { bound, .. } = self.slot.phase.get() else {
            return None;
        };
        if bound.token != token {
            return None;
        }
        self.slot.pid.get()
    }
}

const _: () = {
    assert!(std::mem::size_of::<Backend<'static, 'static, 0>>() == std::mem::size_of::<&()>());
};