Skip to main content

sentinel_driver/types/
lsn.rs

1use bytes::{BufMut, BytesMut};
2
3use crate::error::{Error, Result};
4use crate::types::{FromSql, Oid, ToSql};
5
6/// PostgreSQL PG_LSN type -- a 64-bit Log Sequence Number.
7///
8/// Represents a position in the WAL (write-ahead log).
9/// Wire format is 8 bytes, big-endian u64 (sent as i64 on the wire).
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
11pub struct PgLsn(pub u64);
12
13impl ToSql for PgLsn {
14    fn oid(&self) -> Oid {
15        Oid::PG_LSN
16    }
17
18    fn to_sql(&self, buf: &mut BytesMut) -> Result<()> {
19        buf.put_i64(self.0 as i64);
20        Ok(())
21    }
22}
23
24impl FromSql for PgLsn {
25    fn oid() -> Oid {
26        Oid::PG_LSN
27    }
28
29    fn from_sql(buf: &[u8]) -> Result<Self> {
30        let arr: [u8; 8] = buf
31            .try_into()
32            .map_err(|_| Error::Decode(format!("pg_lsn: expected 8 bytes, got {}", buf.len())))?;
33        Ok(PgLsn(i64::from_be_bytes(arr) as u64))
34    }
35}
36
37impl std::fmt::Display for PgLsn {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        let hi = (self.0 >> 32) as u32;
40        let lo = self.0 as u32;
41        write!(f, "{hi:X}/{lo:X}")
42    }
43}