postgres_protocol/
lib.rs

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)]
13
14use byteorder::{BigEndian, ByteOrder};
15use bytes::{BufMut, BytesMut};
16use std::io;
17
18pub mod authentication;
19pub mod escape;
20pub mod message;
21pub mod password;
22pub mod types;
23
24/// A Postgres OID.
25pub type Oid = u32;
26
27/// A Postgres Log Sequence Number (LSN).
28pub type Lsn = u64;
29
30/// An enum indicating if a value is `NULL` or not.
31pub enum IsNull {
32    /// The value is `NULL`.
33    Yes,
34    /// The value is not `NULL`.
35    No,
36}
37
38fn write_nullable<F, E>(serializer: F, buf: &mut BytesMut) -> Result<(), E>
39where
40    F: FnOnce(&mut BytesMut) -> Result<IsNull, E>,
41    E: From<io::Error>,
42{
43    let base = buf.len();
44    buf.put_i32(0);
45    let 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);
50
51    Ok(())
52}
53
54trait FromUsize: Sized {
55    fn from_usize(x: usize) -> Result<Self, io::Error>;
56}
57
58macro_rules! from_usize {
59    ($t:ty) => {
60        impl FromUsize for $t {
61            #[inline]
62            fn from_usize(x: usize) -> io::Result<$t> {
63                if x > <$t>::MAX as usize {
64                    Err(io::Error::new(
65                        io::ErrorKind::InvalidInput,
66                        "value too large to transmit",
67                    ))
68                } else {
69                    Ok(x as $t)
70                }
71            }
72        }
73    };
74}
75
76from_usize!(i16);
77from_usize!(i32);