From f5e2f296cc7be69c408523e021c92f15ef75cc7e Mon Sep 17 00:00:00 2001 From: meh Date: Wed, 20 Apr 2022 15:08:27 +0200 Subject: [PATCH] Add support for IpAddr --- sqlx-core/src/postgres/types/ipaddr.rs | 62 ++++++++++++++++++++++++++ sqlx-core/src/postgres/types/mod.rs | 3 ++ 2 files changed, 65 insertions(+) create mode 100644 sqlx-core/src/postgres/types/ipaddr.rs diff --git a/sqlx-core/src/postgres/types/ipaddr.rs b/sqlx-core/src/postgres/types/ipaddr.rs new file mode 100644 index 0000000000..56fedc5cf1 --- /dev/null +++ b/sqlx-core/src/postgres/types/ipaddr.rs @@ -0,0 +1,62 @@ +use std::net::IpAddr; + +use ipnetwork::IpNetwork; + +use crate::decode::Decode; +use crate::encode::{Encode, IsNull}; +use crate::error::BoxDynError; +use crate::postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef, Postgres}; +use crate::types::Type; + +impl Type for IpAddr +where + IpNetwork: Type, +{ + fn type_info() -> PgTypeInfo { + IpNetwork::type_info() + } + + fn compatible(ty: &PgTypeInfo) -> bool { + IpNetwork::compatible(ty) + } +} + +impl PgHasArrayType for IpAddr { + fn array_type_info() -> PgTypeInfo { + ::array_type_info() + } + + fn array_compatible(ty: &PgTypeInfo) -> bool { + ::array_compatible(ty) + } +} + +impl<'db> Encode<'db, Postgres> for IpAddr +where + IpNetwork: Encode<'db, Postgres>, +{ + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { + IpNetwork::from(*self).encode_by_ref(buf) + } + + fn size_hint(&self) -> usize { + IpNetwork::from(*self).size_hint() + } +} + +impl<'db> Decode<'db, Postgres> for IpAddr +where + IpNetwork: Decode<'db, Postgres>, +{ + fn decode(value: PgValueRef<'db>) -> Result { + let ipnetwork = IpNetwork::decode(value)?; + + if ipnetwork.is_ipv4() && ipnetwork.prefix() != 32 + || ipnetwork.is_ipv6() && ipnetwork.prefix() != 128 + { + Err("lossy decode from inet/cidr")? + } + + Ok(ipnetwork.ip()) + } +} diff --git a/sqlx-core/src/postgres/types/mod.rs b/sqlx-core/src/postgres/types/mod.rs index 359fe86e14..40d1fc3d78 100644 --- a/sqlx-core/src/postgres/types/mod.rs +++ b/sqlx-core/src/postgres/types/mod.rs @@ -205,6 +205,9 @@ mod json; #[cfg(feature = "ipnetwork")] mod ipnetwork; +#[cfg(feature = "ipnetwork")] +mod ipaddr; + #[cfg(feature = "mac_address")] mod mac_address;