Skip to content

Commit

Permalink
Merge pull request #1164 from allan2/jiff
Browse files Browse the repository at this point in the history
Add Jiff support
  • Loading branch information
sfackler authored Aug 18, 2024
2 parents 2e6b7df + bc9102c commit 6fd0444
Show file tree
Hide file tree
Showing 11 changed files with 344 additions and 0 deletions.
4 changes: 4 additions & 0 deletions postgres-types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Added

* Added support for `jiff` 0.1 via the `with-jiff-01` feature.

## v0.2.7 - 2024-07-21

### Added
Expand Down
2 changes: 2 additions & 0 deletions postgres-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ with-eui48-0_4 = ["eui48-04"]
with-eui48-1 = ["eui48-1"]
with-geo-types-0_6 = ["geo-types-06"]
with-geo-types-0_7 = ["geo-types-0_7"]
with-jiff-0_1 = ["jiff-01"]
with-serde_json-1 = ["serde-1", "serde_json-1"]
with-smol_str-01 = ["smol_str-01"]
with-uuid-0_8 = ["uuid-08"]
Expand All @@ -46,6 +47,7 @@ eui48-04 = { version = "0.4", package = "eui48", optional = true }
eui48-1 = { version = "1.0", package = "eui48", optional = true, default-features = false }
geo-types-06 = { version = "0.6", package = "geo-types", optional = true }
geo-types-0_7 = { version = "0.7", package = "geo-types", optional = true }
jiff-01 = { version = "0.1", package = "jiff", optional = true }
serde-1 = { version = "1.0", package = "serde", optional = true }
serde_json-1 = { version = "1.0", package = "serde_json", optional = true }
uuid-08 = { version = "0.8", package = "uuid", optional = true }
Expand Down
141 changes: 141 additions & 0 deletions postgres-types/src/jiff_01.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use bytes::BytesMut;
use jiff_01::{
civil::{Date, DateTime, Time},
Span, SpanRound, Timestamp, Unit,
};
use postgres_protocol::types;
use std::error::Error;

use crate::{FromSql, IsNull, ToSql, Type};

const fn base() -> DateTime {
DateTime::constant(2000, 1, 1, 0, 0, 0, 0)
}

/// The number of seconds from the Unix epoch to 2000-01-01 00:00:00 UTC.
const PG_EPOCH: i64 = 946684800;

fn base_ts() -> Timestamp {
Timestamp::new(PG_EPOCH, 0).unwrap()
}

fn round_us<'a>() -> SpanRound<'a> {
SpanRound::new().largest(Unit::Microsecond)
}

fn decode_err<E>(_e: E) -> Box<dyn Error + Sync + Send>
where
E: Error,
{
"value too large to decode".into()
}

fn transmit_err<E>(_e: E) -> Box<dyn Error + Sync + Send>
where
E: Error,
{
"value too large to transmit".into()
}

impl<'a> FromSql<'a> for DateTime {
fn from_sql(_: &Type, raw: &[u8]) -> Result<DateTime, Box<dyn Error + Sync + Send>> {
let v = types::timestamp_from_sql(raw)?;
Span::new()
.try_microseconds(v)
.and_then(|s| base().checked_add(s))
.map_err(decode_err)
}

accepts!(TIMESTAMP);
}

impl ToSql for DateTime {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
let v = self
.since(base())
.and_then(|s| s.round(round_us()))
.map_err(transmit_err)?
.get_microseconds();
types::timestamp_to_sql(v, w);
Ok(IsNull::No)
}

accepts!(TIMESTAMP);
to_sql_checked!();
}

impl<'a> FromSql<'a> for Timestamp {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Timestamp, Box<dyn Error + Sync + Send>> {
let v = types::timestamp_from_sql(raw)?;
Span::new()
.try_microseconds(v)
.and_then(|s| base_ts().checked_add(s))
.map_err(decode_err)
}

accepts!(TIMESTAMPTZ);
}

impl ToSql for Timestamp {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
let v = self
.since(base_ts())
.and_then(|s| s.round(round_us()))
.map_err(transmit_err)?
.get_microseconds();
types::timestamp_to_sql(v, w);
Ok(IsNull::No)
}

accepts!(TIMESTAMPTZ);
to_sql_checked!();
}

impl<'a> FromSql<'a> for Date {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Date, Box<dyn Error + Sync + Send>> {
let v = types::date_from_sql(raw)?;
Span::new()
.try_days(v)
.and_then(|s| base().date().checked_add(s))
.map_err(decode_err)
}
accepts!(DATE);
}

impl ToSql for Date {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
let v = self.since(base().date()).map_err(transmit_err)?.get_days();
types::date_to_sql(v, w);
Ok(IsNull::No)
}

accepts!(DATE);
to_sql_checked!();
}

impl<'a> FromSql<'a> for Time {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Time, Box<dyn Error + Sync + Send>> {
let v = types::time_from_sql(raw)?;
Span::new()
.try_microseconds(v)
.and_then(|s| Time::midnight().checked_add(s))
.map_err(decode_err)
}

accepts!(TIME);
}

impl ToSql for Time {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
let v = self
.since(Time::midnight())
.and_then(|s| s.round(round_us()))
.map_err(transmit_err)?
.get_microseconds();
types::time_to_sql(v, w);
Ok(IsNull::No)
}

accepts!(TIME);
to_sql_checked!();
}
6 changes: 6 additions & 0 deletions postgres-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ mod eui48_1;
mod geo_types_06;
#[cfg(feature = "with-geo-types-0_7")]
mod geo_types_07;
#[cfg(feature = "with-jiff-0_1")]
mod jiff_01;
#[cfg(feature = "with-serde_json-1")]
mod serde_json_1;
#[cfg(feature = "with-smol_str-01")]
Expand Down Expand Up @@ -491,6 +493,10 @@ impl WrongType {
/// | `time::OffsetDateTime` | TIMESTAMP WITH TIME ZONE |
/// | `time::Date` | DATE |
/// | `time::Time` | TIME |
/// | `jiff::civil::Date` | DATE |
/// | `jiff::civil::DateTime` | TIMESTAMP |
/// | `jiff::civil::Time` | TIME |
/// | `jiff::Timestamp` | TIMESTAMP WITH TIME ZONE |
/// | `eui48::MacAddress` | MACADDR |
/// | `geo_types::Point<f64>` | POINT |
/// | `geo_types::Rect<f64>` | BOX |
Expand Down
6 changes: 6 additions & 0 deletions postgres/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## Unreleased

### Added

* Added support for `jiff` 0.1 via the `with-jiff-01` feature.

## v0.19.8 - 2024-07-21

### Added
Expand Down
1 change: 1 addition & 0 deletions postgres/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ with-eui48-0_4 = ["tokio-postgres/with-eui48-0_4"]
with-eui48-1 = ["tokio-postgres/with-eui48-1"]
with-geo-types-0_6 = ["tokio-postgres/with-geo-types-0_6"]
with-geo-types-0_7 = ["tokio-postgres/with-geo-types-0_7"]
with-jiff-0_1 = ["tokio-postgres/with-jiff-0_1"]
with-serde_json-1 = ["tokio-postgres/with-serde_json-1"]
with-smol_str-01 = ["tokio-postgres/with-smol_str-01"]
with-uuid-0_8 = ["tokio-postgres/with-uuid-0_8"]
Expand Down
4 changes: 4 additions & 0 deletions tokio-postgres/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Added

* Added support for `jiff` 0.1 via the `with-jiff-01` feature.

## v0.7.11 - 2024-07-21

### Fixed
Expand Down
2 changes: 2 additions & 0 deletions tokio-postgres/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ with-eui48-0_4 = ["postgres-types/with-eui48-0_4"]
with-eui48-1 = ["postgres-types/with-eui48-1"]
with-geo-types-0_6 = ["postgres-types/with-geo-types-0_6"]
with-geo-types-0_7 = ["postgres-types/with-geo-types-0_7"]
with-jiff-0_1 = ["postgres-types/with-jiff-0_1"]
with-serde_json-1 = ["postgres-types/with-serde_json-1"]
with-smol_str-01 = ["postgres-types/with-smol_str-01"]
with-uuid-0_8 = ["postgres-types/with-uuid-0_8"]
Expand Down Expand Up @@ -81,6 +82,7 @@ chrono-04 = { version = "0.4", package = "chrono", default-features = false }
eui48-1 = { version = "1.0", package = "eui48", default-features = false }
geo-types-06 = { version = "0.6", package = "geo-types" }
geo-types-07 = { version = "0.7", package = "geo-types" }
jiff-01 = { version = "0.1", package = "jiff" }
serde-1 = { version = "1.0", package = "serde" }
serde_json-1 = { version = "1.0", package = "serde_json" }
smol_str-01 = { version = "0.1", package = "smol_str" }
Expand Down
1 change: 1 addition & 0 deletions tokio-postgres/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
//! | `with-eui48-1` | Enable support for the 1.0 version of the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 1.0 | no |
//! | `with-geo-types-0_6` | Enable support for the 0.6 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.6.0) 0.6 | no |
//! | `with-geo-types-0_7` | Enable support for the 0.7 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.7.0) 0.7 | no |
//! | `with-jiff-0_1` | Enable support for the 0.1 version of the `jiff` crate. | [jiff](https://crates.io/crates/jiff/0.1.0) 0.1 | no |
//! | `with-serde_json-1` | Enable support for the `serde_json` crate. | [serde_json](https://crates.io/crates/serde_json) 1.0 | no |
//! | `with-uuid-0_8` | Enable support for the `uuid` crate. | [uuid](https://crates.io/crates/uuid) 0.8 | no |
//! | `with-uuid-1` | Enable support for the `uuid` crate. | [uuid](https://crates.io/crates/uuid) 1.0 | no |
Expand Down
Loading

0 comments on commit 6fd0444

Please sign in to comment.