1#![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
24pub type Oid = u32;
26
27pub type Lsn = u64;
29
30pub enum IsNull {
32    Yes,
34    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);