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