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