postgres_types_extra/
pg_macaddr8.rs

1use bytes::{BufMut, BytesMut};
2
3use macaddr::MacAddr8;
4use postgres_types::{FromSql, IsNull, ToSql, Type, accepts, to_sql_checked};
5use std::boxed::Box as StdBox;
6use std::error::Error;
7use std::fmt;
8
9#[derive(Debug, Clone)]
10pub struct PgMacAddr8(MacAddr8);
11
12impl fmt::Display for PgMacAddr8 {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        let w = format!("{}", self.0).to_ascii_lowercase();
15        write!(f, "{w}")
16    }
17}
18
19impl FromSql<'_> for PgMacAddr8 {
20    fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
21        let macaddr8 = macaddr8_from_sql(raw)?;
22        Ok(PgMacAddr8(MacAddr8::new(
23            macaddr8[0],
24            macaddr8[1],
25            macaddr8[2],
26            macaddr8[3],
27            macaddr8[4],
28            macaddr8[5],
29            macaddr8[6],
30            macaddr8[7],
31        )))
32    }
33
34    accepts!(MACADDR8);
35}
36
37impl ToSql for PgMacAddr8 {
38    fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
39        let mut bytes = [0; 8];
40        bytes.copy_from_slice(self.0.as_bytes());
41        macaddr8_to_sql(bytes, w);
42        Ok(IsNull::No)
43    }
44
45    accepts!(MACADDR8);
46    to_sql_checked!();
47}
48
49/// Serializes a `MACADDR8` value.
50#[inline]
51pub fn macaddr8_to_sql(v: [u8; 8], buf: &mut BytesMut) {
52    buf.put_slice(&v);
53}
54
55/// Deserializes a `MACADDR8` value.
56#[inline]
57pub fn macaddr8_from_sql(buf: &[u8]) -> Result<[u8; 8], StdBox<dyn Error + Sync + Send>> {
58    if buf.len() != 8 {
59        return Err("invalid message length: macaddr length mismatch".into());
60    }
61    let mut out = [0; 8];
62    out.copy_from_slice(buf);
63    Ok(out)
64}