Skip to content

Commit c8e9639

Browse files
committed
Added display trait for interval
1 parent 2e97c1a commit c8e9639

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

Diff for: Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "pg-interval-sql-json-binding"
33
description = "Postgres SQL and Serde JSON binding for crates/pg_interval"
4-
version = "1.1.0"
4+
version = "1.2.0"
55
license-file = "LICENSE"
66
repository = "https://github.com/techbech/pg-interval-sql-json-binding"
77
readme = "README.md"

Diff for: src/lib.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use postgres_types::private::BytesMut;
99
use serde::{Deserialize, Serialize};
1010
use serde::ser::{SerializeStruct};
1111
use std::convert::TryInto;
12-
use std::fmt::{Display, Formatter};
12+
use std::fmt::{Display, Formatter, Write};
1313

1414
#[derive(Debug, PartialEq, Eq)]
1515
pub struct ParseError {
@@ -78,6 +78,49 @@ impl FromStr for Interval {
7878
}
7979
}
8080

81+
impl Display for Interval {
82+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
83+
let years = self.pg.months / 12;
84+
let months = self.pg.months % 12;
85+
let days = self.pg.days;
86+
let hours = self.pg.microseconds / 3_600_000_000;
87+
let minutes = (self.pg.microseconds % 3_600_000_000) / 60_000_000;
88+
let seconds = (self.pg.microseconds % 60_000_000) / 1_000_000;
89+
let milliseconds = self.pg.microseconds % 1_000_000 / 1_000;
90+
let microseconds = self.pg.microseconds % 1_000;
91+
let mut buf = String::new();
92+
if years > 0 {
93+
write!(buf, "{} years ", years)?;
94+
}
95+
if months > 0 {
96+
write!(buf, "{} mons ", months)?;
97+
}
98+
if days > 0 {
99+
write!(buf, "{} days ", days)?;
100+
}
101+
if hours > 0 {
102+
write!(buf, "{} hours ", hours)?;
103+
}
104+
if minutes > 0 {
105+
write!(buf, "{} minutes ", minutes)?;
106+
}
107+
if seconds > 0 {
108+
write!(buf, "{} seconds ", seconds)?;
109+
}
110+
if milliseconds > 0 {
111+
write!(buf, "{} milliseconds ", milliseconds)?;
112+
}
113+
if microseconds > 0 {
114+
write!(buf, "{} microseconds ", microseconds)?;
115+
}
116+
if buf.is_empty() {
117+
write!(buf, "0 seconds")
118+
} else {
119+
write!(f, "{}", &buf.as_str()[..buf.len() - 1])
120+
}
121+
}
122+
}
123+
81124
impl<'a> FromSql<'a> for Interval {
82125
fn from_sql(_: &Type, raw: &[u8]) -> Result<Interval, Box<dyn Error + Sync + Send>> {
83126
Ok(Interval {
@@ -217,6 +260,27 @@ mod tests {
217260
assert_eq!(buf.as_ref(), &[0, 0, 0, 0, 0, 45, 198, 192, 0, 0, 0, 2, 0, 0, 0, 1]);
218261
}
219262

263+
#[test]
264+
fn test_interval_display() {
265+
let interval = Interval {
266+
pg: pg_interval::Interval {
267+
months: 14,
268+
days: 3,
269+
microseconds: 4 * 3600000000 + 5 * 60000000 + 6 * 1000000 + 7 * 1000 + 8,
270+
}
271+
};
272+
assert_eq!(format!("{}", interval), "1 years 2 mons 3 days 4 hours 5 minutes 6 seconds 7 milliseconds 8 microseconds");
273+
274+
let interval = Interval {
275+
pg: pg_interval::Interval {
276+
months: 1,
277+
days: 2,
278+
microseconds: 3 * 1000000,
279+
}
280+
};
281+
assert_eq!(interval.to_string(), "1 mons 2 days 3 seconds");
282+
}
283+
220284
#[test]
221285
fn test_interval_serialize() {
222286
let interval = Interval {

0 commit comments

Comments
 (0)