postgres_types_extra/
pg_snapshot.rs

1use byteorder::{NetworkEndian, ReadBytesExt};
2use bytes::BufMut;
3use postgres_types::{FromSql, IsNull, ToSql, Type, to_sql_checked};
4use std::error::Error;
5use std::fmt;
6use std::io::Cursor;
7
8#[derive(Debug, PartialEq)]
9pub struct PgSnapshot {
10    xmin: i64,
11    xmax: i64,
12    xip_list: Vec<i64>,
13}
14
15impl<'a> FromSql<'a> for PgSnapshot {
16    fn from_sql(_ty: &Type, raw: &'a [u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
17        let mut rdr = Cursor::new(raw);
18
19        let nxip = rdr.read_i32::<NetworkEndian>()?;
20        let xmin = rdr.read_i64::<NetworkEndian>()?;
21        let xmax = rdr.read_i64::<NetworkEndian>()?;
22
23        let mut xip_list = Vec::with_capacity(nxip as usize);
24        for _ in 0..nxip {
25            xip_list.push(rdr.read_i64::<NetworkEndian>()?);
26        }
27
28        Ok(PgSnapshot {
29            xmin,
30            xmax,
31            xip_list,
32        })
33    }
34
35    fn accepts(ty: &Type) -> bool {
36        ty.name() == "pg_snapshot"
37    }
38}
39
40impl ToSql for PgSnapshot {
41    fn to_sql(
42        &self,
43        _ty: &Type,
44        out: &mut bytes::BytesMut,
45    ) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
46        out.put_i32(self.xip_list.len() as i32);
47        out.put_i64(self.xmin);
48        out.put_i64(self.xmax);
49
50        for &xip in &self.xip_list {
51            out.put_i64(xip);
52        }
53
54        Ok(IsNull::No)
55    }
56
57    fn accepts(ty: &Type) -> bool {
58        ty.name() == "pg_snapshot"
59    }
60
61    to_sql_checked!();
62}
63
64impl fmt::Display for PgSnapshot {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        write!(f, "{}:{}", self.xmin, self.xmax)?;
67        if !self.xip_list.is_empty() {
68            write!(f, ":")?;
69            for (i, xip) in self.xip_list.iter().enumerate() {
70                if i > 0 {
71                    write!(f, ",")?;
72                }
73                write!(f, "{xip}")?;
74            }
75        } else {
76            write!(f, ":")?;
77        }
78        Ok(())
79    }
80}