From 9685f9c532f10bd99339e2dcddaad3b462c5b687 Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Wed, 16 Mar 2022 14:13:36 +1000 Subject: [PATCH 1/3] Add ToSql / FromSql for IpInet and IpCidr from cidr crate --- postgres-types/Cargo.toml | 2 ++ postgres-types/src/cidr_02.rs | 44 +++++++++++++++++++++++++++++++++++ postgres-types/src/lib.rs | 2 ++ 3 files changed, 48 insertions(+) create mode 100644 postgres-types/src/cidr_02.rs diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 7eca3fbcf..1954d51bb 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -14,6 +14,7 @@ categories = ["database"] derive = ["postgres-derive"] array-impls = ["array-init"] with-bit-vec-0_6 = ["bit-vec-06"] +with-cidr-0_2 = ["cidr-02"] with-chrono-0_4 = ["chrono-04"] with-eui48-0_4 = ["eui48-04"] with-eui48-1 = ["eui48-1"] @@ -32,6 +33,7 @@ postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-deri array-init = { version = "2", optional = true } bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } +cidr-02 = { version = "0.2", package = "cidr", optional = true } chrono-04 = { version = "0.4.16", package = "chrono", default-features = false, features = ["clock"], optional = true } eui48-04 = { version = "0.4", package = "eui48", optional = true } eui48-1 = { version = "1.0", package = "eui48", optional = true } diff --git a/postgres-types/src/cidr_02.rs b/postgres-types/src/cidr_02.rs new file mode 100644 index 000000000..46e904483 --- /dev/null +++ b/postgres-types/src/cidr_02.rs @@ -0,0 +1,44 @@ +use bytes::BytesMut; +use cidr_02::{IpCidr, IpInet}; +use postgres_protocol::types; +use std::error::Error; + +use crate::{FromSql, IsNull, ToSql, Type}; + +impl<'a> FromSql<'a> for IpCidr { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let inet = types::inet_from_sql(raw)?; + Ok(IpCidr::new(inet.addr(), inet.netmask()).expect("postgres cidr type has zeroed host portion")) + } + + accepts!(CIDR); +} + +impl ToSql for IpCidr { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + types::inet_to_sql(self.first_address(), self.network_length(), w); + Ok(IsNull::No) + } + + accepts!(CIDR); + to_sql_checked!(); +} + +impl<'a> FromSql<'a> for IpInet { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let inet = types::inet_from_sql(raw)?; + Ok(IpInet::new(inet.addr(), inet.netmask()).expect("postgres enforces maximum length of netmask")) + } + + accepts!(INET); +} + +impl ToSql for IpInet { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + types::inet_to_sql(self.address(), self.network_length(), w); + Ok(IsNull::No) + } + + accepts!(INET); + to_sql_checked!(); +} diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 0247b90b7..b1a45bab1 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -210,6 +210,8 @@ where #[cfg(feature = "with-bit-vec-0_6")] mod bit_vec_06; +#[cfg(feature = "with-cidr-0_2")] +mod cidr_02; #[cfg(feature = "with-chrono-0_4")] mod chrono_04; #[cfg(feature = "with-eui48-0_4")] From dd7bc073f7a7dfd1a1dd9c3e90e5d9d1630a2824 Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Wed, 16 Mar 2022 14:32:50 +1000 Subject: [PATCH 2/3] Document cidr type conversion and run rustfmt --- postgres-types/Cargo.toml | 2 +- postgres-types/src/cidr_02.rs | 6 ++++-- postgres-types/src/lib.rs | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 1954d51bb..9d470f37b 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -33,8 +33,8 @@ postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-deri array-init = { version = "2", optional = true } bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } -cidr-02 = { version = "0.2", package = "cidr", optional = true } chrono-04 = { version = "0.4.16", package = "chrono", default-features = false, features = ["clock"], optional = true } +cidr-02 = { version = "0.2", package = "cidr", optional = true } eui48-04 = { version = "0.4", package = "eui48", optional = true } eui48-1 = { version = "1.0", package = "eui48", optional = true } geo-types-06 = { version = "0.6", package = "geo-types", optional = true } diff --git a/postgres-types/src/cidr_02.rs b/postgres-types/src/cidr_02.rs index 46e904483..d4e4965c5 100644 --- a/postgres-types/src/cidr_02.rs +++ b/postgres-types/src/cidr_02.rs @@ -8,7 +8,8 @@ use crate::{FromSql, IsNull, ToSql, Type}; impl<'a> FromSql<'a> for IpCidr { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpCidr::new(inet.addr(), inet.netmask()).expect("postgres cidr type has zeroed host portion")) + Ok(IpCidr::new(inet.addr(), inet.netmask()) + .expect("postgres cidr type has zeroed host portion")) } accepts!(CIDR); @@ -27,7 +28,8 @@ impl ToSql for IpCidr { impl<'a> FromSql<'a> for IpInet { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpInet::new(inet.addr(), inet.netmask()).expect("postgres enforces maximum length of netmask")) + Ok(IpInet::new(inet.addr(), inet.netmask()) + .expect("postgres enforces maximum length of netmask")) } accepts!(INET); diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index b1a45bab1..394f938ff 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -210,10 +210,10 @@ where #[cfg(feature = "with-bit-vec-0_6")] mod bit_vec_06; -#[cfg(feature = "with-cidr-0_2")] -mod cidr_02; #[cfg(feature = "with-chrono-0_4")] mod chrono_04; +#[cfg(feature = "with-cidr-0_2")] +mod cidr_02; #[cfg(feature = "with-eui48-0_4")] mod eui48_04; #[cfg(feature = "with-eui48-1")] @@ -438,6 +438,8 @@ impl WrongType { /// | `uuid::Uuid` | UUID | /// | `bit_vec::BitVec` | BIT, VARBIT | /// | `eui48::MacAddress` | MACADDR | +/// | `cidr::InetCidr` | CIDR | +/// | `cidr::InetAddr` | INET | /// /// # Nullability /// From 27039f6c3a9f05a41b657f1db5489d055363e2a8 Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Thu, 17 Mar 2022 09:31:13 +1000 Subject: [PATCH 3/3] Change error handling in `cidr` `FromSql` implementations --- postgres-types/src/cidr_02.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/postgres-types/src/cidr_02.rs b/postgres-types/src/cidr_02.rs index d4e4965c5..2de952c3c 100644 --- a/postgres-types/src/cidr_02.rs +++ b/postgres-types/src/cidr_02.rs @@ -8,8 +8,7 @@ use crate::{FromSql, IsNull, ToSql, Type}; impl<'a> FromSql<'a> for IpCidr { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpCidr::new(inet.addr(), inet.netmask()) - .expect("postgres cidr type has zeroed host portion")) + Ok(IpCidr::new(inet.addr(), inet.netmask())?) } accepts!(CIDR); @@ -28,8 +27,7 @@ impl ToSql for IpCidr { impl<'a> FromSql<'a> for IpInet { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpInet::new(inet.addr(), inet.netmask()) - .expect("postgres enforces maximum length of netmask")) + Ok(IpInet::new(inet.addr(), inet.netmask())?) } accepts!(INET);