diesel/pg/types/
pg_lsn.rs
1use diesel_derives::AsExpression;
2use diesel_derives::FromSqlRow;
3
4use super::sql_types;
5use crate::deserialize::{self, FromSql};
6use crate::pg::{Pg, PgValue};
7use crate::serialize::{self, IsNull, Output, ToSql};
8use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
9
10#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, AsExpression, FromSqlRow)]
13#[diesel(sql_type = sql_types::PgLsn)]
14pub struct PgLsn(pub u64);
15
16#[cfg(feature = "postgres_backend")]
17impl FromSql<sql_types::PgLsn, Pg> for PgLsn {
18 fn from_sql(value: PgValue<'_>) -> deserialize::Result<Self> {
19 let mut bytes = value.as_bytes();
20 if bytes.len() < 8 {
21 return emit_size_error(
22 "Received less than 8 bytes while decoding a pg_lsn. \
23 Was an Integer expression accidentally marked as pg_lsn?",
24 );
25 }
26
27 if bytes.len() > 8 {
28 return emit_size_error(
29 "Received more than 8 bytes while decoding a pg_lsn. \
30 Was an expression of a different type expression accidentally marked as pg_lsn?"
31 );
32 }
33 let val = bytes
34 .read_u64::<NetworkEndian>()
35 .map_err(|e| Box::new(e) as Box<_>)?;
36 Ok(PgLsn(val))
37 }
38}
39
40#[cold]
41#[inline(never)]
42fn emit_size_error<T>(var_name: &str) -> deserialize::Result<T> {
43 deserialize::Result::Err(var_name.into())
44}
45
46#[cfg(feature = "postgres_backend")]
47impl ToSql<sql_types::PgLsn, Pg> for PgLsn {
48 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
49 out.write_u64::<NetworkEndian>(self.0)
50 .map(|_| IsNull::No)
51 .map_err(Into::into)
52 }
53}
54
55#[cfg(test)]
56#[diesel_test_helper::test]
57fn lsn_roundtrip() {
58 use crate::query_builder::bind_collector::ByteWrapper;
59
60 let mut buffer = Vec::new();
61 let mut bytes = Output::test(ByteWrapper(&mut buffer));
62 let input_lsn = PgLsn(0x525400fbc61617ff);
63 ToSql::<sql_types::PgLsn, Pg>::to_sql(&input_lsn, &mut bytes).unwrap();
64 let output_lsn: PgLsn = FromSql::from_sql(PgValue::for_test(&buffer)).unwrap();
65 assert_eq!(input_lsn, output_lsn);
66}