1//! Low level Postgres protocol APIs.
2//!
3//! This crate implements the low level components of Postgres's communication
4//! protocol, including message and value serialization and deserialization.
5//! It is designed to be used as a building block by higher level APIs such as
6//! `rust-postgres`, and should not typically be used directly.
7//!
8//! # Note
9//!
10//! This library assumes that the `client_encoding` backend parameter has been
11//! set to `UTF8`. It will most likely not behave properly if that is not the case.
12#![warn(missing_docs, rust_2018_idioms, clippy::all)]
1314use byteorder::{BigEndian, ByteOrder};
15use bytes::{BufMut, BytesMut};
16use std::io;
1718pub mod authentication;
19pub mod escape;
20pub mod message;
21pub mod password;
22pub mod types;
2324/// A Postgres OID.
25pub type Oid = u32;
2627/// A Postgres Log Sequence Number (LSN).
28pub type Lsn = u64;
2930/// An enum indicating if a value is `NULL` or not.
31pub enum IsNull {
32/// The value is `NULL`.
33Yes,
34/// The value is not `NULL`.
35No,
36}
3738fn write_nullable<F, E>(serializer: F, buf: &mut BytesMut) -> Result<(), E>
39where
40F: FnOnce(&mut BytesMut) -> Result<IsNull, E>,
41 E: From<io::Error>,
42{
43let base = buf.len();
44 buf.put_i32(0);
45let size = match serializer(buf)? {
46 IsNull::No => i32::from_usize(buf.len() - base - 4)?,
47 IsNull::Yes => -1,
48 };
49 BigEndian::write_i32(&mut buf[base..], size);
5051Ok(())
52}
5354trait FromUsize: Sized {
55fn from_usize(x: usize) -> Result<Self, io::Error>;
56}
5758macro_rules! from_usize {
59 ($t:ty) => {
60impl FromUsize for $t {
61#[inline]
62fn from_usize(x: usize) -> io::Result<$t> {
63if x > <$t>::MAX as usize {
64Err(io::Error::new(
65 io::ErrorKind::InvalidInput,
66"value too large to transmit",
67 ))
68 } else {
69Ok(x as $t)
70 }
71 }
72 }
73 };
74}
7576from_usize!(i16);
77from_usize!(i32);