libpq 6.0.1

Safe binding for libpq
Documentation
#[derive(Clone, Debug)]
pub struct Cancel {
    cancel: *mut pq_sys::pg_cancel_conn,
}

impl Cancel {
    /**
     * Prepares a connection over which a cancel request can be sent.
     *
     * See [PQcancelCreate](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELCREATE).
     */
    pub fn create(conn: &crate::Connection) -> crate::errors::Result<Self> {
        unsafe { pq_sys::PQcancelCreate(conn.into()) }.try_into()
    }

    /**
     * Requests that the server abandons processing of the current command in a blocking manner.
     *
     * See [PQcancelBlocking](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELBLOCKING).
     */
    pub fn blocking(&mut self) -> crate::errors::Result {
        let success = unsafe { pq_sys::PQcancelBlocking(self.into()) };

        if success == 0 {
            Ok(())
        } else {
            Err(crate::errors::Error::Backend(self.error_message()))
        }
    }

    /**
     * Requests that the server abandons processing of the current command in a non-blocking manner.
     *
     * See [PQcancelStart](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSTART).
     */
    pub fn start(&mut self) -> crate::errors::Result {
        let success = unsafe { pq_sys::PQcancelStart(self.into()) };

        if success == 0 {
            Ok(())
        } else {
            Err(crate::errors::Error::Backend(self.error_message()))
        }
    }

    /**
     * Requests that the server abandons processing of the current command in a non-blocking manner.
     *
     * See [PQcancelPoll](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSTART).
     */
    pub fn pool(&mut self) -> crate::poll::Status {
        unsafe { pq_sys::PQcancelPoll(self.into()) }.into()
    }

    /**
     * Returns the status of the cancel connection.
     *
     * See [PQcancelStatus](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSTATUS).
     */
    pub fn status(&self) -> crate::connection::Status {
        unsafe { pq_sys::PQcancelStatus(self.into()) }.into()
    }

    /**
     * Obtains the file descriptor number of the cancel connection socket to the server.
     *
     * See [PQcancelSocket](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSOCKET).
     */
    pub fn socket(&self) -> crate::errors::Result<std::os::fd::RawFd> {
        let fd = unsafe { pq_sys::PQcancelSocket(self.into()) };

        if fd >= 0 {
            Ok(fd)
        } else {
            Err(crate::errors::Error::Backend(
                "No server connection is currently open".to_string(),
            ))
        }
    }

    /**
     * Returns the error message most recently generated by an operation on the cancel connection.
     *
     * See [PQcancelErrorMessage](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELERRORMESSAGE).
     */
    pub fn error_message(&self) -> String {
        let error = unsafe { pq_sys::PQcancelErrorMessage(self.into()) };

        match unsafe { std::ffi::CStr::from_ptr(error) }.to_str() {
            Ok(s) => s.to_string(),
            Err(_) => "PQerrorMessage internal error: the error message is not UTF-8".to_string(),
        }
    }

    /**
     * Closes the cancel connection (if it did not finish sending the cancel request yet).
     *
     * See [PQcancelFinish](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELFINISH).
     */
    fn finish(&mut self) {
        unsafe { pq_sys::PQcancelFinish(self.into()) };
    }

    /**
     * Resets the `CancelConn` so it can be reused for a new cancel connection.
     *
     * See [PQcancelReset](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELRESET).
     */
    pub fn reset(&mut self) {
        unsafe { pq_sys::PQcancelReset(self.into()) };
    }
}

#[doc(hidden)]
impl TryFrom<*mut pq_sys::pg_cancel_conn> for Cancel {
    type Error = crate::errors::Error;

    fn try_from(cancel: *mut pq_sys::pg_cancel_conn) -> std::result::Result<Self, Self::Error> {
        if cancel.is_null() {
            Err(crate::errors::Error::Backend(
                "Unable to create cancel request".to_string(),
            ))
        } else {
            Ok(Self { cancel })
        }
    }
}

#[doc(hidden)]
impl From<&mut Cancel> for *mut pq_sys::pg_cancel_conn {
    fn from(cancel: &mut Cancel) -> *mut pq_sys::pg_cancel_conn {
        cancel.cancel
    }
}

#[doc(hidden)]
impl From<&Cancel> for *const pq_sys::pg_cancel_conn {
    fn from(cancel: &Cancel) -> *const pq_sys::pg_cancel_conn {
        cancel.cancel
    }
}

impl Drop for Cancel {
    fn drop(&mut self) {
        self.finish();
    }
}