From 86d42231e7e52e61652e9e413794398eec9fc328 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:16:32 -0500 Subject: [PATCH 01/12] add support, version current features --- Cargo.toml | 40 +++++---- README.md | 50 +++++------ src/lib.rs | 98 +++++++++++---------- tests/consume.rs | 222 ++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 293 insertions(+), 117 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5bb3b4f..e4df33c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pgde" -version = "0.6.0" +version = "0.7.0" authors = ["Paul Caruso "] license = "MIT" edition = "2021" @@ -11,28 +11,32 @@ categories = [ "api-bindings", "development-tools::ffi", "rust-patterns" ] keywords = ["postgresql"] [features] -bit = ["dep:bit-vec", "tokio-postgres/with-bit-vec-0_6"] -chrono = ["dep:chrono", "tokio-postgres/with-chrono-0_4"] -consume_json = ["dep:serde", "dep:serde_json"] -geo = ["dep:geo-types", "tokio-postgres/with-geo-types-0_7"] -mac = ["dep:eui48", "tokio-postgres/with-eui48-1"] -json = ["dep:serde_json", "tokio-postgres/with-serde_json-1"] -time = ["dep:time", "tokio-postgres/with-time-0_3"] -uuid = ["dep:uuid", "tokio-postgres/with-uuid-1"] +bit_0_6 = ["dep:bit-vec_0_6", "tokio-postgres/with-bit-vec-0_6"] +bit_0_7 = ["dep:bit-vec_0_7", "tokio-postgres/with-bit-vec-0_7"] +bit_0_8 = ["dep:bit-vec_0_8", "tokio-postgres/with-bit-vec-0_8"] +chrono_0_4 = ["dep:chrono_0_4", "tokio-postgres/with-chrono-0_4"] +consume_json_1 = ["dep:serde_1", "dep:serde_json_1"] +geo_0_7 = ["dep:geo-types_0_7", "tokio-postgres/with-geo-types-0_7"] +mac_1 = ["dep:eui48_1", "tokio-postgres/with-eui48-1"] +json_1 = ["dep:serde_json_1", "tokio-postgres/with-serde_json-1"] +time_0_3 = ["dep:time_0_3", "tokio-postgres/with-time-0_3"] +uuid_1 = ["dep:uuid_1", "tokio-postgres/with-uuid-1"] [dependencies] -bit-vec = { version = "0.6", optional = true } -chrono = { version = "0.4", optional = true } -eui48 = { version = "1.1", optional = true } -geo-types = { version = "0.7", optional = true } +bit-vec_0_6 = { package = "bit-vec", version = "0.6", optional = true } +bit-vec_0_7 = { package = "bit-vec", version = "0.7", optional = true } +bit-vec_0_8 = { package = "bit-vec", version = "0.8", optional = true } +chrono_0_4 = { package = "chrono", version = "0.4", optional = true } +eui48_1 = { package = "eui48", version = "1.1", optional = true } +geo-types_0_7 = { package = "geo-types", version = "0.7", optional = true } pgde_derive = { version = "0.2" } -serde = { version = "1.0", features = ["derive"], optional = true } -serde_json = { version = "1.0", optional = true } -time = { version = "0.3", optional = true } +serde_1 = { package = "serde", version = "1.0", features = ["derive"], optional = true } +serde_json_1 = { package = "serde_json", version = "1.0", optional = true } +time_0_3 = { package = "time", version = "0.3", optional = true } tokio-postgres = { version = "0.7" } -uuid = { version = "1.10", features = ["v4"], optional = true } +uuid_1 = { package = "uuid", version = "1.0", features = ["v4"], optional = true } [dev-dependencies] -time = { version = "0.3", features = ["macros"] } +time_0_3 = { package = "time", version = "0.3", features = ["macros"] } tokio = { version = "1", features = ["full"] } tokio-test = { version = "0.4" } \ No newline at end of file diff --git a/README.md b/README.md index 8a87b4b..22579fe 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,14 @@ A variety of features provide support for additional implementation and types. | Feature | Description | Extra dependencies | Default | | ------- | ----------- | ------------------ | ------- | -| `bit` | Implements crate on `bit_vec::BitVec` | bit-vec | No | -| `chrono` | Implements crate on types supplied by chrono | chrono | No | -| `consume_json` | Implements `consume_json` on classes that derive the `RowConsumer` trait | serde, serde_json | No | -| `geo` | Implements crate on `geo_types::Point`, `geo_types::Rect`, and `geo_types::LineString` | geo-types | No | -| `mac` | Implements crate on `eui48::MacAddress` | eui48 | No | -| `json` | Implements crate on `serde_json::Value` | serde_json | No | -| `time` | Implements crate on types supplied by time | time | No | -| `uuid` | Implements crate on `uuid::Uuid` | uuid | No | +| `bit_{0_6, 0_7, 0_8}` | Implements crate on `bit_vec::BitVec` | bit-vec | No | +| `chrono_0_4` | Implements crate on types supplied by chrono | chrono | No | +| `consume_json_1` | Implements `consume_json` on classes that derive the `RowConsumer` trait | serde, serde_json | No | +| `geo_0_7` | Implements crate on `geo_types::Point`, `geo_types::Rect`, and `geo_types::LineString` | geo-types | No | +| `mac_1` | Implements crate on `eui48::MacAddress` | eui48 | No | +| `json_1` | Implements crate on `serde_json::Value` | serde_json | No | +| `time_0_3` | Implements crate on types supplied by time | time | No | +| `uuid_1` | Implements crate on `uuid::Uuid` | uuid | No | ## Examples You may use `consume` to consume PostgreSQL row data into a struct like so. @@ -87,23 +87,23 @@ This crate also provides implementations on a variety of data types, some provid | `String` | `default` | | `SystemTime` | `default` | | `IpAddr` | `default` | -| `bit_vec::BitVec` | `bit` | -| `chrono::NaiveDateTime` | `chrono` | -| `chrono::DateTime` | `chrono` | -| `chrono::DateTime` | `chrono` | -| `chrono::DateTime` | `chrono` | -| `chrono::NaiveDate` | `chrono` | -| `chrono::NaiveTime` | `chrono` | -| `geo_types::Point` | `geo` | -| `geo_types::Rect` | `geo` | -| `geo_types::LineString` | `geo` | -| `eui48::MacAddress` | `mac` | -| `serde_json::Value` | `json` | -| `time::PrimitiveDateTime` | `time` | -| `time::OffsetDateTime` | `time` | -| `time::Date` | `time` | -| `time::Time` | `time` | -| `uuid::Uuid` | `uuid` | +| `bit_vec::BitVec` | `bit_{0_6, 0_7, 0_8}` | +| `chrono::NaiveDateTime` | `chrono_0_4` | +| `chrono::DateTime` | `chrono_0_4` | +| `chrono::DateTime` | `chrono_0_4` | +| `chrono::DateTime` | `chrono_0_4` | +| `chrono::NaiveDate` | `chrono_0_4` | +| `chrono::NaiveTime` | `chrono_0_4` | +| `geo_types::Point` | `geo_0_7` | +| `geo_types::Rect` | `geo_0_7` | +| `geo_types::LineString` | `geo_0_7` | +| `eui48::MacAddress` | `mac_1` | +| `serde_json::Value` | `json_1` | +| `time::PrimitiveDateTime` | `time_0_3` | +| `time::OffsetDateTime` | `time_0_3` | +| `time::Date` | `time_0_3` | +| `time::Time` | `time_0_3` | +| `uuid::Uuid` | `uuid_1` | ## Testing Testing requires access to a PostgreSQL database with no tables. Setting the following environment variables will allow you to test. diff --git a/src/lib.rs b/src/lib.rs index 2f604f4..d0c61c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,14 +13,14 @@ //! //! | Feature | Description | Extra dependencies | Default | //! | ------- | ----------- | ------------------ | ------- | -//! | `bit` | Implements crate on `bit_vec::BitVec` | bit-vec | No | -//! | `chrono` | Implements crate on types supplied by chrono | chrono | No | -//! | `consume_json` | Implements `consume_json` on classes that derive the `RowConsumer` trait | serde, serde_json | No | -//! | `geo` | Implements crate on `geo_types::Point`, `geo_types::Rect`, and `geo_types::LineString` | geo-types | No | -//! | `mac` | Implements crate on `eui48::MacAddress` | eui48 | No | -//! | `json` | Implements crate on `serde_json::Value` | serde_json | No | -//! | `time` | Implements crate on types supplied by time | time | No | -//! | `uuid` | Implements crate on `uuid::Uuid` | uuid | No | +//! | `bit_{0_6, 0_7, 0_8}` | Implements crate on `bit_vec::BitVec` | bit-vec | No | +//! | `chrono_0_4` | Implements crate on types supplied by chrono | chrono | No | +//! | `consume_json_1` | Implements `consume_json` on classes that derive the `RowConsumer` trait | serde, serde_json | No | +//! | `geo_0_7` | Implements crate on `geo_types::Point`, `geo_types::Rect`, and `geo_types::LineString` | geo-types | No | +//! | `mac_1` | Implements crate on `eui48::MacAddress` | eui48 | No | +//! | `json_1` | Implements crate on `serde_json::Value` | serde_json | No | +//! | `time_0_3` | Implements crate on types supplied by time | time | No | +//! | `uuid_1` | Implements crate on `uuid::Uuid` | uuid | No | //! //! ## Examples //! You may use `consume` to consume PostgreSQL row data into a struct like so. @@ -87,23 +87,23 @@ //! | `String` | `default` | //! | `SystemTime` | `default` | //! | `IpAddr` | `default` | -//! | `bit_vec::BitVec` | `bit` | -//! | `chrono::NaiveDateTime` | `chrono` | -//! | `chrono::DateTime` | `chrono` | -//! | `chrono::DateTime` | `chrono` | -//! | `chrono::DateTime` | `chrono` | -//! | `chrono::NaiveDate` | `chrono` | -//! | `chrono::NaiveTime` | `chrono` | -//! | `geo_types::Point` | `geo` | -//! | `geo_types::Rect` | `geo` | -//! | `geo_types::LineString` | `geo` | -//! | `eui48::MacAddress` | `mac` | -//! | `serde_json::Value` | `json` | -//! | `time::PrimitiveDateTime` | `time` | -//! | `time::OffsetDateTime` | `time` | -//! | `time::Date` | `time` | -//! | `time::Time` | `time` | -//! | `uuid::Uuid` | `uuid` | +//! | `bit_vec::BitVec` | `bit_{0_6, 0_7, 0_8}` | +//! | `chrono::NaiveDateTime` | `chrono_0_4` | +//! | `chrono::DateTime` | `chrono_0_4` | +//! | `chrono::DateTime` | `chrono_0_4` | +//! | `chrono::DateTime` | `chrono_0_4` | +//! | `chrono::NaiveDate` | `chrono_0_4` | +//! | `chrono::NaiveTime` | `chrono_0_4` | +//! | `geo_types::Point` | `geo_0_7` | +//! | `geo_types::Rect` | `geo_0_7` | +//! | `geo_types::LineString` | `geo_0_7` | +//! | `eui48::MacAddress` | `mac_1` | +//! | `serde_json::Value` | `json_1` | +//! | `time::PrimitiveDateTime` | `time_0_3` | +//! | `time::OffsetDateTime` | `time_0_3` | +//! | `time::Date` | `time_0_3` | +//! | `time::Time` | `time_0_3` | +//! | `uuid::Uuid` | `uuid_1` | //! //! ## Testing //! Testing requires access to a PostgreSQL database with no tables. Setting the following environment variables will allow you to test. @@ -114,34 +114,38 @@ //! | `POSTGRES_USER` | The user credential to provide. | //! | `POSTGRES_PASSWORD` | The password to provide. | //! | `POSTGRES_DB` | The name of the database to use for testing. | -#[cfg(feature = "bit")] +#[cfg(feature = "bit_0_6")] use bit_vec::BitVec; -#[cfg(feature = "chrono")] +#[cfg(feature = "bit_0_7")] +use bit_vec::BitVec; +#[cfg(feature = "bit_0_8")] +use bit_vec::BitVec; +#[cfg(feature = "chrono_0_4")] use chrono::prelude::*; -#[cfg(feature = "mac")] +#[cfg(feature = "mac_1")] use eui48::MacAddress; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::coord; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::line_string; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::LineString; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::Point; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::Rect; -#[cfg(feature = "consume_json")] +#[cfg(feature = "consume_json_1")] use serde::Serialize; use std::future::Future; use std::net::IpAddr; use std::net::Ipv4Addr; use std::time::SystemTime; -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] use time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; use tokio_postgres::row::Row; use tokio_postgres::types::ToSql; use tokio_postgres::Client; -#[cfg(feature = "uuid")] +#[cfg(feature = "uuid_1")] use uuid::Uuid; /// Errors that may occur during row consumption. @@ -399,7 +403,7 @@ pub trait RowConsumer { /// }; /// # }) /// ``` - #[cfg(feature = "consume_json")] + #[cfg(feature = "consume_json_1")] fn consume_json( conn: &Client, query: &str, @@ -527,10 +531,14 @@ pg_type_expr_implementation![ Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))) ]; -#[cfg(feature = "bit")] +#[cfg(feature = "bit_0_6")] +pg_type_implementation![BitVec, Vec, Option]; +#[cfg(feature = "bit_0_7")] +pg_type_implementation![BitVec, Vec, Option]; +#[cfg(feature = "bit_0_8")] pg_type_implementation![BitVec, Vec, Option]; -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] pg_type_implementation![ NaiveDateTime, DateTime, @@ -552,10 +560,10 @@ pg_type_implementation![ Option ]; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] pg_type_implementation![Point, Vec>, Option>]; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] pg_type_expr_implementation![ Rect, Rect::new(coord! { x: 0., y: 0.}, coord! { x: 1., y: 1.},), @@ -580,10 +588,10 @@ pg_type_expr_implementation![ ]) ]; -#[cfg(feature = "mac")] +#[cfg(feature = "mac_1")] pg_type_implementation![MacAddress, Vec, Option]; -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] pg_type_expr_implementation![ PrimitiveDateTime, PrimitiveDateTime::MIN, @@ -611,10 +619,10 @@ pg_type_expr_implementation![ Some(Time::MIDNIGHT) ]; -#[cfg(feature = "uuid")] +#[cfg(feature = "uuid_1")] pg_type_implementation![Uuid, Vec, Option]; -#[cfg(feature = "json")] +#[cfg(feature = "json_1")] pg_type_implementation![ serde_json::Value, Vec, diff --git a/tests/consume.rs b/tests/consume.rs index 108ee7e..64a063f 100644 --- a/tests/consume.rs +++ b/tests/consume.rs @@ -1,32 +1,36 @@ //! Attempts to test a variety of `consume` scenarios for data types mentioned in the provided `FromSql` type implementations from postgres_types. -#[cfg(feature = "bit")] +#[cfg(feature = "bit_0_6")] use bit_vec::BitVec; -#[cfg(feature = "chrono")] +#[cfg(feature = "bit_0_7")] +use bit_vec::BitVec; +#[cfg(feature = "bit_0_8")] +use bit_vec::BitVec; +#[cfg(feature = "chrono_0_4")] use chrono::prelude::*; -#[cfg(feature = "mac")] +#[cfg(feature = "mac_1")] use eui48::MacAddress; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::coord; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::line_string; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::point; -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] use geo_types::Rect; use pgde::RowConsumer; use pgde_derive::RowConsumer; -#[cfg(feature = "consume_json")] +#[cfg(feature = "consume_json_1")] use serde::Serialize; -#[cfg(feature = "json")] +#[cfg(feature = "json_1")] use serde_json::json; use std::net::IpAddr; use std::net::Ipv4Addr; use std::time::SystemTime; -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] use time::{macros::*, Date, OffsetDateTime, PrimitiveDateTime, Time}; use tokio_postgres::Row; use tokio_postgres::{Client, NoTls}; -#[cfg(feature = "uuid")] +#[cfg(feature = "uuid_1")] use uuid::Uuid; #[macro_export] @@ -754,7 +758,7 @@ async fn consume_ip() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "mac")] +#[cfg(feature = "mac_1")] async fn consume_macaddress() -> Result<(), String> { db_env_assertion!(); @@ -814,7 +818,7 @@ async fn consume_macaddress() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] async fn consume_point() -> Result<(), String> { db_env_assertion!(); @@ -872,7 +876,7 @@ async fn consume_point() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] async fn consume_rect() -> Result<(), String> { db_env_assertion!(); @@ -928,7 +932,7 @@ async fn consume_rect() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "geo")] +#[cfg(feature = "geo_0_7")] async fn consume_linestring() -> Result<(), String> { db_env_assertion!(); @@ -991,7 +995,7 @@ async fn consume_linestring() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "json")] +#[cfg(feature = "json_1")] async fn consume_json() -> Result<(), String> { db_env_assertion!(); @@ -1078,7 +1082,7 @@ async fn consume_json() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "uuid")] +#[cfg(feature = "uuid_1")] async fn consume_uuid() -> Result<(), String> { db_env_assertion!(); @@ -1130,7 +1134,167 @@ async fn consume_uuid() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "bit")] +#[cfg(feature = "bit_0_6")] +async fn consume_bits() -> Result<(), String> { + db_env_assertion!(); + + match connect_to_database().await { + Ok(v) => match v + .query( + "create table if not exists consume_bits ( + field1 bit(16), + field2 varbit(16) + );", + &[], + ) + .await + { + Ok(_) => { + let test_bits = BitVec::from_bytes(&[0b10100000, 0b00010010]); + + match v + .query( + "insert into public.\"consume_bits\" values ( $1, $2 );", + &[&test_bits, &test_bits], + ) + .await + { + Ok(_) => { + match BitVec::consume( + &v, + "select field1 from public.\"consume_bits\";", + &[], + ) + .await + { + Ok(result) => match result.last() { + Some(result_value) => { + assert_eq!( + *result_value, test_bits, + "Could not consume bit into BitVec" + ); + + match BitVec::consume( + &v, + "select field2 from public.\"consume_bits\";", + &[], + ) + .await + { + Ok(result) => match result.last() { + Some(result_value) => { + assert_eq!( + *result_value, test_bits, + "Could not consume varbit into BitVec" + ); + + Ok(()) + } + None => Err(String::from( + "Could not consume varbit into BitVec", + )), + }, + Err(_) => Err(String::from( + "Could not consume varbit into BitVec", + )), + } + } + None => Err(String::from("Could not consume bit into BitVec")), + }, + Err(_) => Err(String::from("Could not consume bit into BitVec")), + } + } + Err(v) => Err(v.to_string()), + } + } + Err(v) => Err(v.to_string()), + }, + Err(_) => Err(String::from("Could not connect to database")), + } +} + +#[tokio::test] +#[cfg(feature = "bit_0_7")] +async fn consume_bits() -> Result<(), String> { + db_env_assertion!(); + + match connect_to_database().await { + Ok(v) => match v + .query( + "create table if not exists consume_bits ( + field1 bit(16), + field2 varbit(16) + );", + &[], + ) + .await + { + Ok(_) => { + let test_bits = BitVec::from_bytes(&[0b10100000, 0b00010010]); + + match v + .query( + "insert into public.\"consume_bits\" values ( $1, $2 );", + &[&test_bits, &test_bits], + ) + .await + { + Ok(_) => { + match BitVec::consume( + &v, + "select field1 from public.\"consume_bits\";", + &[], + ) + .await + { + Ok(result) => match result.last() { + Some(result_value) => { + assert_eq!( + *result_value, test_bits, + "Could not consume bit into BitVec" + ); + + match BitVec::consume( + &v, + "select field2 from public.\"consume_bits\";", + &[], + ) + .await + { + Ok(result) => match result.last() { + Some(result_value) => { + assert_eq!( + *result_value, test_bits, + "Could not consume varbit into BitVec" + ); + + Ok(()) + } + None => Err(String::from( + "Could not consume varbit into BitVec", + )), + }, + Err(_) => Err(String::from( + "Could not consume varbit into BitVec", + )), + } + } + None => Err(String::from("Could not consume bit into BitVec")), + }, + Err(_) => Err(String::from("Could not consume bit into BitVec")), + } + } + Err(v) => Err(v.to_string()), + } + } + Err(v) => Err(v.to_string()), + }, + Err(_) => Err(String::from("Could not connect to database")), + } +} + +#[tokio::test] +#[cfg(feature = "bit_0_8")] async fn consume_bits() -> Result<(), String> { db_env_assertion!(); @@ -1210,7 +1374,7 @@ async fn consume_bits() -> Result<(), String> { } #[tokio::test] -#[cfg(feature = "consume_json")] +#[cfg(feature = "consume_json_1")] async fn consume_json_impl() -> Result<(), String> { db_env_assertion!(); @@ -1292,7 +1456,7 @@ async fn consume_option_unit() -> Result<(), String> { } } -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] #[tokio::test] async fn consume_chrono_naivedatetime() -> Result<(), String> { db_env_assertion!(); @@ -1350,7 +1514,7 @@ async fn consume_chrono_naivedatetime() -> Result<(), String> { } } -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] #[tokio::test] async fn consume_chrono_datetime_utc() -> Result<(), String> { db_env_assertion!(); @@ -1408,7 +1572,7 @@ async fn consume_chrono_datetime_utc() -> Result<(), String> { } } -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] #[tokio::test] async fn consume_chrono_datetime_local() -> Result<(), String> { db_env_assertion!(); @@ -1466,7 +1630,7 @@ async fn consume_chrono_datetime_local() -> Result<(), String> { } } -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] #[tokio::test] async fn consume_chrono_datetime_fixedoffset() -> Result<(), String> { db_env_assertion!(); @@ -1528,7 +1692,7 @@ async fn consume_chrono_datetime_fixedoffset() -> Result<(), String> { } } -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] #[tokio::test] async fn consume_chrono_naivedate() -> Result<(), String> { db_env_assertion!(); @@ -1582,7 +1746,7 @@ async fn consume_chrono_naivedate() -> Result<(), String> { } } -#[cfg(feature = "chrono")] +#[cfg(feature = "chrono_0_4")] #[tokio::test] async fn consume_chrono_naivetime() -> Result<(), String> { db_env_assertion!(); @@ -1636,7 +1800,7 @@ async fn consume_chrono_naivetime() -> Result<(), String> { } } -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] #[tokio::test] async fn consume_time_primitivedatetime() -> Result<(), String> { db_env_assertion!(); @@ -1695,7 +1859,7 @@ async fn consume_time_primitivedatetime() -> Result<(), String> { } } -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] #[tokio::test] async fn consume_time_offsetdatetime() -> Result<(), String> { db_env_assertion!(); @@ -1754,7 +1918,7 @@ async fn consume_time_offsetdatetime() -> Result<(), String> { } } -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] #[tokio::test] async fn consume_time_date() -> Result<(), String> { db_env_assertion!(); @@ -1809,7 +1973,7 @@ async fn consume_time_date() -> Result<(), String> { } } -#[cfg(feature = "time")] +#[cfg(feature = "time_0_3")] #[tokio::test] async fn consume_time_time() -> Result<(), String> { db_env_assertion!(); From 3b6839a7eb0186de7cd87c6bf28ca511b353430b Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:19:29 -0500 Subject: [PATCH 02/12] Update workflow to match new feature names --- .github/workflows/rust.yml | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b99346f..8f3d431 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -36,27 +36,31 @@ jobs: run: cargo build - name: Build features independently run: | - cargo build -Fbit - cargo build -Fchrono - cargo build -Fconsume_json - cargo build -Fgeo - cargo build -Fmac - cargo build -Fjson - cargo build -Ftime - cargo build -Fuuid + cargo build -Fbit_0_6 + cargo build -Fbit_0_7 + cargo build -Fbit_0_8 + cargo build -Fchrono_0_4 + cargo build -Fconsume_json_1 + cargo build -Fgeo_0_7 + cargo build -Fmac_1 + cargo build -Fjson_1 + cargo build -Ftime_0_3 + cargo build -Fuuid_1 - name: Build all features run: cargo build --all-features - name: Test base run: cargo test --tests - name: Test features independently run: | - cargo test -Fbit - cargo test -Fchrono - cargo test -Fconsume_json - cargo test -Fgeo - cargo test -Fmac - cargo test -Fjson - cargo test -Ftime - cargo test -Fuuid + cargo test -Fbit_0_6 + cargo test -Fbit_0_7 + cargo test -Fbit_0_8 + cargo test -Fchrono_0_4 + cargo test -Fconsume_json_1 + cargo test -Fgeo_0_7 + cargo test -Fmac_1 + cargo test -Fjson_1 + cargo test -Ftime_0_3 + cargo test -Fuuid_1 - name: Test all features run: cargo test --all-features From c02962e46b56731d5a51e69581938a0143e05489 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:24:51 -0500 Subject: [PATCH 03/12] Update lib.rs --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d0c61c5..7ba9be1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,11 +115,11 @@ //! | `POSTGRES_PASSWORD` | The password to provide. | //! | `POSTGRES_DB` | The name of the database to use for testing. | #[cfg(feature = "bit_0_6")] -use bit_vec::BitVec; +use bit_vec_0_6::BitVec; #[cfg(feature = "bit_0_7")] -use bit_vec::BitVec; +use bit_vec_0_7::BitVec; #[cfg(feature = "bit_0_8")] -use bit_vec::BitVec; +use bit_vec_0_8::BitVec; #[cfg(feature = "chrono_0_4")] use chrono::prelude::*; #[cfg(feature = "mac_1")] From debaf11439af3e17d5d5878f5f2586313ca00be3 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:31:59 -0500 Subject: [PATCH 04/12] use external crates correctly --- src/lib.rs | 32 ++++++++++++++++---------------- tests/consume.rs | 26 +++++++++++++------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7ba9be1..72b653f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,32 +121,32 @@ use bit_vec_0_7::BitVec; #[cfg(feature = "bit_0_8")] use bit_vec_0_8::BitVec; #[cfg(feature = "chrono_0_4")] -use chrono::prelude::*; +use chrono_0_4::prelude::*; #[cfg(feature = "mac_1")] -use eui48::MacAddress; +use eui48_1::MacAddress; #[cfg(feature = "geo_0_7")] -use geo_types::coord; +use geo_types_0_7::coord; #[cfg(feature = "geo_0_7")] -use geo_types::line_string; +use geo_types_0_7::line_string; #[cfg(feature = "geo_0_7")] -use geo_types::LineString; +use geo_types_0_7::LineString; #[cfg(feature = "geo_0_7")] -use geo_types::Point; +use geo_types_0_7::Point; #[cfg(feature = "geo_0_7")] -use geo_types::Rect; +use geo_types_0_7::Rect; #[cfg(feature = "consume_json_1")] -use serde::Serialize; +use serde_1::Serialize; use std::future::Future; use std::net::IpAddr; use std::net::Ipv4Addr; use std::time::SystemTime; #[cfg(feature = "time_0_3")] -use time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; +use time_0_3::{Date, OffsetDateTime, PrimitiveDateTime, Time}; use tokio_postgres::row::Row; use tokio_postgres::types::ToSql; use tokio_postgres::Client; #[cfg(feature = "uuid_1")] -use uuid::Uuid; +use uuid_1::Uuid; /// Errors that may occur during row consumption. pub enum ConsumeError { @@ -414,11 +414,11 @@ pub trait RowConsumer { { async move { match &Self::consume(conn, query, params).await { - Ok(v) => match serde_json::to_string(v) { + Ok(v) => match serde_json_1::to_string(v) { Ok(v) => Ok(v), - Err(_) => Err(serde_json::Value::default().to_string()), + Err(_) => Err(serde_json_1::Value::default().to_string()), }, - Err(_) => Err(serde_json::Value::default().to_string()), + Err(_) => Err(serde_json_1::Value::default().to_string()), } } } @@ -624,7 +624,7 @@ pg_type_implementation![Uuid, Vec, Option]; #[cfg(feature = "json_1")] pg_type_implementation![ - serde_json::Value, - Vec, - Option + serde_json_1::Value, + Vec, + Option ]; diff --git a/tests/consume.rs b/tests/consume.rs index 64a063f..e600a23 100644 --- a/tests/consume.rs +++ b/tests/consume.rs @@ -1,37 +1,37 @@ //! Attempts to test a variety of `consume` scenarios for data types mentioned in the provided `FromSql` type implementations from postgres_types. #[cfg(feature = "bit_0_6")] -use bit_vec::BitVec; +use bit_vec_0_6::BitVec; #[cfg(feature = "bit_0_7")] -use bit_vec::BitVec; +use bit_vec_0_7::BitVec; #[cfg(feature = "bit_0_8")] -use bit_vec::BitVec; +use bit_vec_0_8::BitVec; #[cfg(feature = "chrono_0_4")] -use chrono::prelude::*; +use chrono_0_4::prelude::*; #[cfg(feature = "mac_1")] -use eui48::MacAddress; +use eui48_1::MacAddress; #[cfg(feature = "geo_0_7")] -use geo_types::coord; +use geo_types_0_7::coord; #[cfg(feature = "geo_0_7")] -use geo_types::line_string; +use geo_types_0_7::line_string; #[cfg(feature = "geo_0_7")] -use geo_types::point; +use geo_types_0_7::point; #[cfg(feature = "geo_0_7")] -use geo_types::Rect; +use geo_types_0_7::Rect; use pgde::RowConsumer; use pgde_derive::RowConsumer; #[cfg(feature = "consume_json_1")] -use serde::Serialize; +use serde_1::Serialize; #[cfg(feature = "json_1")] -use serde_json::json; +use serde_json_1::json; use std::net::IpAddr; use std::net::Ipv4Addr; use std::time::SystemTime; #[cfg(feature = "time_0_3")] -use time::{macros::*, Date, OffsetDateTime, PrimitiveDateTime, Time}; +use time_0_3::{macros::*, Date, OffsetDateTime, PrimitiveDateTime, Time}; use tokio_postgres::Row; use tokio_postgres::{Client, NoTls}; #[cfg(feature = "uuid_1")] -use uuid::Uuid; +use uuid_1::Uuid; #[macro_export] macro_rules! db_env_assertion { From a273e9366572c98209e800e7ab81f65309ef7a2c Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:35:39 -0500 Subject: [PATCH 05/12] break apart all features test to avoid version overlap --- .github/workflows/rust.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8f3d431..6ae7697 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -63,4 +63,7 @@ jobs: cargo test -Ftime_0_3 cargo test -Fuuid_1 - name: Test all features - run: cargo test --all-features + run: | + cargo test -Fbit_0_6 -Fchrono_0_4 -Fconsume_json_1 -Fgeo_0_7 -Fmac_1 -Fjson_1 -Ftime_0_3 -Fuuid_1 + cargo test -Fbit_0_7 -Fchrono_0_4 -Fconsume_json_1 -Fgeo_0_7 -Fmac_1 -Fjson_1 -Ftime_0_3 -Fuuid_1 + cargo test -Fbit_0_8 -Fchrono_0_4 -Fconsume_json_1 -Fgeo_0_7 -Fmac_1 -Fjson_1 -Ftime_0_3 -Fuuid_1 From 0737cfaf6f7f93f0b63ff850b7e4b8aa479f17e9 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:37:30 -0500 Subject: [PATCH 06/12] got tests, meant to get builds too lol --- .github/workflows/rust.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 6ae7697..a5c3c87 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -47,7 +47,10 @@ jobs: cargo build -Ftime_0_3 cargo build -Fuuid_1 - name: Build all features - run: cargo build --all-features + run: | + cargo build -Fbit_0_6 -Fchrono_0_4 -Fconsume_json_1 -Fgeo_0_7 -Fmac_1 -Fjson_1 -Ftime_0_3 -Fuuid_1 + cargo build -Fbit_0_7 -Fchrono_0_4 -Fconsume_json_1 -Fgeo_0_7 -Fmac_1 -Fjson_1 -Ftime_0_3 -Fuuid_1 + cargo build -Fbit_0_8 -Fchrono_0_4 -Fconsume_json_1 -Fgeo_0_7 -Fmac_1 -Fjson_1 -Ftime_0_3 -Fuuid_1 - name: Test base run: cargo test --tests - name: Test features independently From 5ac658d84397dc6bdae804eb893af6c8d727693e Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 05:56:08 -0500 Subject: [PATCH 07/12] serde-rs/serde #856 --- tests/consume.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/consume.rs b/tests/consume.rs index e600a23..031e84e 100644 --- a/tests/consume.rs +++ b/tests/consume.rs @@ -20,7 +20,7 @@ use geo_types_0_7::Rect; use pgde::RowConsumer; use pgde_derive::RowConsumer; #[cfg(feature = "consume_json_1")] -use serde_1::Serialize; +use serde_1::{self, Serialize}; #[cfg(feature = "json_1")] use serde_json_1::json; use std::net::IpAddr; @@ -1379,6 +1379,7 @@ async fn consume_json_impl() -> Result<(), String> { db_env_assertion!(); #[derive(Serialize, RowConsumer)] + #[serde(crate = "self::serde_1")] struct Foo { foo: i32, bar: i32, From fa11fabf855a48649319f7f18527d43cd7b41095 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 06:01:17 -0500 Subject: [PATCH 08/12] Update lib.rs --- src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 72b653f..3ed09ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -135,7 +135,7 @@ use geo_types_0_7::Point; #[cfg(feature = "geo_0_7")] use geo_types_0_7::Rect; #[cfg(feature = "consume_json_1")] -use serde_1::Serialize; +use serde_1::{self, Serialize}; use std::future::Future; use std::net::IpAddr; use std::net::Ipv4Addr; @@ -370,10 +370,11 @@ pub trait RowConsumer { /// use pgde::ConsumeError; /// use pgde::RowConsumer; /// use pgde_derive::RowConsumer; - /// use serde::Serialize; + /// use serde_1::{self, Serialize}; /// use tokio_postgres::{NoTls, Row}; /// /// #[derive(Serialize, RowConsumer)] + /// #[serde(crate = "self::serde_1")] /// struct Foo { /// Id: i32, /// Data: String, From 5d2db431faf549e1ce0a621ab5aec9d393087784 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 06:15:17 -0500 Subject: [PATCH 09/12] Update consume.rs --- tests/consume.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/consume.rs b/tests/consume.rs index 031e84e..404c74b 100644 --- a/tests/consume.rs +++ b/tests/consume.rs @@ -27,7 +27,7 @@ use std::net::IpAddr; use std::net::Ipv4Addr; use std::time::SystemTime; #[cfg(feature = "time_0_3")] -use time_0_3::{macros::*, Date, OffsetDateTime, PrimitiveDateTime, Time}; +use time_0_3::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time}; use tokio_postgres::Row; use tokio_postgres::{Client, NoTls}; #[cfg(feature = "uuid_1")] @@ -843,7 +843,7 @@ async fn consume_point() -> Result<(), String> { .await { Ok(_) => { - match geo_types::Point::::consume( + match geo_types_0_7::Point::::consume( &v, "select field1 from public.\"consume_point\";", &[], @@ -901,7 +901,7 @@ async fn consume_rect() -> Result<(), String> { .await { Ok(_) => { - match geo_types::Rect::::consume( + match geo_types_0_7::Rect::::consume( &v, "select field1 from public.\"consume_rect\";", &[], @@ -960,7 +960,7 @@ async fn consume_linestring() -> Result<(), String> { .await { Ok(_) => { - match geo_types::LineString::::consume( + match geo_types_0_7::LineString::::consume( &v, "select field1 from public.\"consume_linestring\";", &[], @@ -1028,7 +1028,7 @@ async fn consume_json() -> Result<(), String> { .await { Ok(_) => { - match serde_json::Value::consume( + match serde_json_1::Value::consume( &v, "select field1 from public.\"consume_json\";", &[], @@ -1042,7 +1042,7 @@ async fn consume_json() -> Result<(), String> { "Could not consume json into Value" ); - match serde_json::Value::consume( + match serde_json_1::Value::consume( &v, "select field2 from public.\"consume_json\";", &[], @@ -1817,7 +1817,7 @@ async fn consume_time_primitivedatetime() -> Result<(), String> { .await { Ok(_) => { - let test_datetime = datetime!(2020-01-01 0:00); + let test_datetime = Date::from_calendar_date(2020, Month::January, 1).unwrap().midnight(); match v .query( @@ -1876,7 +1876,7 @@ async fn consume_time_offsetdatetime() -> Result<(), String> { .await { Ok(_) => { - let test_datetime = datetime!(2020-01-01 0:00 UTC); + let test_datetime = Date::from_calendar_date(2020, Month::January, 1).unwrap().midnight().assume_utc(); match v .query( @@ -1935,7 +1935,7 @@ async fn consume_time_date() -> Result<(), String> { .await { Ok(_) => { - let test_date = date!(2020 - 01 - 01); + let test_date = Date::from_calendar_date(2020, Month::January, 1).unwrap(); match v .query( @@ -1990,7 +1990,7 @@ async fn consume_time_time() -> Result<(), String> { .await { Ok(_) => { - let test_time = time!(5:00); + let test_time = Time::from_hms(5, 0, 0).unwrap(); match v .query( From 26a12447689f242f0577c92c05b155d29623ecd7 Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 06:15:54 -0500 Subject: [PATCH 10/12] Update consume.rs --- tests/consume.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/consume.rs b/tests/consume.rs index 404c74b..da5ee1b 100644 --- a/tests/consume.rs +++ b/tests/consume.rs @@ -1817,7 +1817,9 @@ async fn consume_time_primitivedatetime() -> Result<(), String> { .await { Ok(_) => { - let test_datetime = Date::from_calendar_date(2020, Month::January, 1).unwrap().midnight(); + let test_datetime = Date::from_calendar_date(2020, Month::January, 1) + .unwrap() + .midnight(); match v .query( @@ -1876,7 +1878,10 @@ async fn consume_time_offsetdatetime() -> Result<(), String> { .await { Ok(_) => { - let test_datetime = Date::from_calendar_date(2020, Month::January, 1).unwrap().midnight().assume_utc(); + let test_datetime = Date::from_calendar_date(2020, Month::January, 1) + .unwrap() + .midnight() + .assume_utc(); match v .query( From 81029ace97878f178978c84dc53f159ad15e044e Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 06:28:33 -0500 Subject: [PATCH 11/12] hm --- Cargo.toml | 1 + src/lib.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e4df33c..4f053bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ description = "A macro library for consuming PostgreSQL row data into structs." readme = "README.md" categories = [ "api-bindings", "development-tools::ffi", "rust-patterns" ] keywords = ["postgresql"] +doctest = false [features] bit_0_6 = ["dep:bit-vec_0_6", "tokio-postgres/with-bit-vec-0_6"] diff --git a/src/lib.rs b/src/lib.rs index 3ed09ef..2a1c8c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -370,11 +370,10 @@ pub trait RowConsumer { /// use pgde::ConsumeError; /// use pgde::RowConsumer; /// use pgde_derive::RowConsumer; - /// use serde_1::{self, Serialize}; + /// use serde::Serialize; /// use tokio_postgres::{NoTls, Row}; /// /// #[derive(Serialize, RowConsumer)] - /// #[serde(crate = "self::serde_1")] /// struct Foo { /// Id: i32, /// Data: String, From a8a1dd3eccc402dc733cc117992a0fe0d5caad0e Mon Sep 17 00:00:00 2001 From: crusopaul Date: Fri, 28 Nov 2025 06:30:35 -0500 Subject: [PATCH 12/12] pls stop doctesting --- Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 4f053bd..55ad300 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ description = "A macro library for consuming PostgreSQL row data into structs." readme = "README.md" categories = [ "api-bindings", "development-tools::ffi", "rust-patterns" ] keywords = ["postgresql"] + +[lib] doctest = false [features]