elefant-client 0.1.0

A pure rust implementation of a postgres client that is independent of the executor runtime
Documentation
use crate::protocol::frame_reader::ByteSliceWriter;
use std::borrow::Cow;

#[derive(Debug, PartialEq, Eq)]
pub enum FrontendPMessage<'a> {
    SASLInitialResponse(SASLInitialResponse<'a>),
    SASLResponse(SASLResponse<'a>),
    GSSResponse(GSSResponse<'a>),
    PasswordMessage(PasswordMessage<'a>),
    Undecided(UndecidedFrontendPMessage<'a>),
}

#[derive(Debug, PartialEq, Eq)]
pub struct SASLInitialResponse<'a> {
    pub mechanism: Cow<'a, str>,
    pub data: Option<&'a [u8]>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct SASLResponse<'a> {
    pub data: &'a [u8],
}

#[derive(Debug, PartialEq, Eq)]
pub struct GSSResponse<'a> {
    pub data: &'a [u8],
}

#[derive(Debug, PartialEq, Eq)]
pub struct PasswordMessage<'a> {
    pub password: Cow<'a, str>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct UndecidedFrontendPMessage<'a> {
    pub data: &'a [u8],
}

impl FrontendPMessage<'_> {
    pub(crate) fn write_to(&self, destination: &mut ByteSliceWriter) {
        match self {
            FrontendPMessage::SASLInitialResponse(sasl) => {
                destination.write_u8(b'p');

                let length =
                    4 + sasl.mechanism.len() + 1 + 4 + sasl.data.map(|d| d.len()).unwrap_or(0);

                destination.write_i32(length as i32);
                destination.write_null_terminated_string(&sasl.mechanism);
                if let Some(data) = sasl.data {
                    destination.write_i32(data.len() as i32);
                    destination.write_bytes(data);
                } else {
                    destination.write_i32(-1);
                }
            }
            FrontendPMessage::SASLResponse(sasl) => {
                destination.write_u8(b'p');
                destination.write_i32(4 + sasl.data.len() as i32);
                destination.write_bytes(sasl.data);
            }
            FrontendPMessage::GSSResponse(gss) => {
                destination.write_u8(b'p');
                destination.write_i32(4 + gss.data.len() as i32);
                destination.write_bytes(gss.data);
            }
            FrontendPMessage::PasswordMessage(pw) => {
                destination.write_u8(b'p');
                destination.write_i32(4 + pw.password.len() as i32 + 1);
                destination.write_null_terminated_string(&pw.password);
            }
            FrontendPMessage::Undecided(undecided) => {
                destination.write_u8(b'p');
                destination.write_i32(4 + undecided.data.len() as i32);
                destination.write_bytes(undecided.data);
            }
        }
    }
}