postgres_types_extra/
pg_cidr.rs1use bytes::BytesMut;
2use cidr::{IpCidr, IpInet};
3use postgres_protocol::types;
4use postgres_types::{FromSql, IsNull, ToSql, Type, accepts, to_sql_checked};
5use std::{error::Error, fmt};
6
7#[derive(Debug, Clone)]
8pub struct PgCidr(IpCidr);
9
10#[derive(Debug, Clone)]
11
12pub struct PgInet(IpInet);
13
14impl fmt::Display for PgCidr {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 let w = format!("{}", self.0).to_ascii_lowercase();
17 write!(f, "{w}")
18 }
19}
20
21impl FromSql<'_> for PgCidr {
22 fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
23 let inet = types::inet_from_sql(raw)?;
24 Ok(PgCidr(IpCidr::new(inet.addr(), inet.netmask())?))
25 }
26
27 accepts!(CIDR);
28}
29
30impl ToSql for PgCidr {
31 fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
32 types::inet_to_sql(self.0.first_address(), self.0.network_length(), w);
33 Ok(IsNull::No)
34 }
35
36 accepts!(CIDR);
37 to_sql_checked!();
38}
39
40impl fmt::Display for PgInet {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 let w = format!("{}", self.0).to_ascii_lowercase();
43 write!(f, "{w}")
44 }
45}
46impl FromSql<'_> for PgInet {
47 fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
48 let inet = types::inet_from_sql(raw)?;
49 Ok(PgInet(IpInet::new(inet.addr(), inet.netmask())?))
50 }
51
52 accepts!(INET);
53}
54
55impl ToSql for PgInet {
56 fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
57 types::inet_to_sql(self.0.address(), self.0.network_length(), w);
58 Ok(IsNull::No)
59 }
60
61 accepts!(INET);
62 to_sql_checked!();
63
64 fn encode_format(&self, _ty: &Type) -> postgres_types::Format {
65 postgres_types::Format::Binary
66 }
67}