Skip to content

Commit

Permalink
postgres: create chrono_truncate_nanos and time_truncate_nanos
Browse files Browse the repository at this point in the history
  • Loading branch information
dimtion committed Apr 24, 2020
1 parent afb8764 commit bd27d0e
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions sqlx-core/src/postgres/types/interval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ impl Encode<Postgres> for PgInterval {
impl TryFrom<PgInterval> for chrono::Duration {
type Error = crate::Error;

/// Convert a `PgInterval` to a `chrono::Duration`
///
/// The convertion will fail if any of the fields `days` or `months` is different to 0.
fn try_from(value: PgInterval) -> crate::Result<chrono::Duration> {
match (value.days, value.months) {
(0, 0) => Ok(Self::microseconds(value.microseconds)),
Expand All @@ -80,6 +83,14 @@ impl TryFrom<PgInterval> for chrono::Duration {
impl TryFrom<chrono::Duration> for PgInterval {
type Error = crate::Error;

/// Convert a `chrono::Duration to a `PgInterval`
///
/// The convertion will fail if there is a loss of precision with the nanoseconds. To do a
/// lossy conversion use `PgInterval::chrono_truncate_nanos()`.
///
/// # Panics
///
/// The convertion panics if there is an overflow with the microseconds or nanoseconds
fn try_from(value: chrono::Duration) -> crate::Result<Self> {
let microseconds = value.num_microseconds().expect("Microseconds overflow");
match value
Expand All @@ -100,10 +111,60 @@ impl TryFrom<chrono::Duration> for PgInterval {
}
}

impl PgInterval {
/// Convert a `time::Duration` object to a `PgInterval` object but truncate the remaining nanoseconds.
/// # Panics
///
/// Panics if there is an overflow retrieving the microseconds
///
/// # Example
///
/// ```
/// use sqlx_core::postgres::types::PgInterval;
/// let interval = PgInterval::time_truncate_nanos(time::Duration::seconds(3_600));
/// assert_eq!(interval, PgInterval { months: 0, days: 0, microseconds: 3_600_000_000 });
/// ```
#[cfg(feature = "time")]
pub fn time_truncate_nanos(value: time::Duration) -> Self {
let microseconds =
i64::try_from(value.whole_microseconds()).expect("Microseconds overflow");
Self {
months: 0,
days: 0,
microseconds,
}
}

/// Convert a `chrono::Duration` object to a `PgInterval` object but truncates the remaining nanoseconds.
/// # Panics
///
/// Panics if there is an overflow retrieving the microseconds
///
/// # Example
///
/// ```
/// use sqlx_core::postgres::types::PgInterval;
/// let interval = PgInterval::chrono_truncate_nanos(chrono::Duration::seconds(3_600));
/// assert_eq!(interval, PgInterval { months: 0, days: 0, microseconds: 3_600_000_000 });
/// ```
#[cfg(feature = "chrono")]
pub fn chrono_truncate_nanos(value: chrono::Duration) -> Self {
let microseconds = value.num_microseconds().expect("Microseconds overflow");
Self {
months: 0,
days: 0,
microseconds,
}
}
}

#[cfg(feature = "time")]
impl TryFrom<PgInterval> for time::Duration {
type Error = crate::Error;

/// Convert a `PgInterval` to a `time::Duration`
///
/// The convertion will fail if any of the fields `days` or `months` is different to 0.
fn try_from(value: PgInterval) -> crate::Result<Self> {
match (value.days, value.months) {
(0, 0) => Ok(Self::microseconds(value.microseconds)),
Expand All @@ -118,6 +179,14 @@ impl TryFrom<PgInterval> for time::Duration {
impl TryFrom<time::Duration> for PgInterval {
type Error = crate::Error;

/// Convert a `time::Duration to a `PgInterval`
///
/// The convertion will fail if there is a loss of precision with the nanoseconds. To do a
/// lossy conversion use `PgInterval::time_truncate_nanos()`.
///
/// # Panics
///
/// The convertion panics if there is an overflow with the microseconds
fn try_from(value: time::Duration) -> crate::Result<Self> {
let microseconds =
i64::try_from(value.whole_microseconds()).expect("Microseconds overflow");
Expand Down

0 comments on commit bd27d0e

Please sign in to comment.