Skip to content

Commit

Permalink
feat(prost-types): Add normalized functions (#1158)
Browse files Browse the repository at this point in the history
Make `normalize` easier to use, by introducing `Duration::normalized` and `Timestamp::normalized`. They do the same as there `normalize` equivalents, but return a copy for ease of use.
  • Loading branch information
caspermeijn committed Sep 20, 2024
1 parent 644c328 commit 8d4cac5
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
5 changes: 1 addition & 4 deletions prost-types/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,10 +989,7 @@ mod tests {
let date_time = DateTime::from(timestamp);
let roundtrip = Timestamp::try_from(date_time).unwrap();

let mut normalized_timestamp = timestamp;
normalized_timestamp.normalize();

prop_assert_eq!(normalized_timestamp, roundtrip);
prop_assert_eq!(timestamp.normalized(), roundtrip);
}

#[test]
Expand Down
24 changes: 16 additions & 8 deletions prost-types/src/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ impl Duration {
// debug_assert!(self.seconds >= -315_576_000_000 && self.seconds <= 315_576_000_000,
// "invalid duration: {:?}", self);
}

/// Returns a normalized copy of the duration to a canonical format.
///
/// Based on [`google::protobuf::util::CreateNormalized`][1].
///
/// [1]: https://github.com/google/protobuf/blob/v3.3.2/src/google/protobuf/util/time_util.cc#L79-L100
pub fn normalized(&self) -> Self {
let mut result = *self;
result.normalize();
result
}
}

impl Name for Duration {
Expand All @@ -77,9 +88,8 @@ impl TryFrom<time::Duration> for Duration {
let seconds = i64::try_from(duration.as_secs()).map_err(|_| DurationError::OutOfRange)?;
let nanos = duration.subsec_nanos() as i32;

let mut duration = Duration { seconds, nanos };
duration.normalize();
Ok(duration)
let duration = Duration { seconds, nanos };
Ok(duration.normalized())
}
}

Expand All @@ -105,8 +115,7 @@ impl TryFrom<Duration> for time::Duration {

impl fmt::Display for Duration {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = *self;
d.normalize();
let d = self.normalized();
if self.seconds < 0 || self.nanos < 0 {
write!(f, "-")?;
}
Expand Down Expand Up @@ -407,14 +416,13 @@ mod tests {
];

for case in cases.iter() {
let mut test_duration = Duration {
let test_duration = Duration {
seconds: case.1,
nanos: case.2,
};
test_duration.normalize();

assert_eq!(
test_duration,
test_duration.normalized(),
Duration {
seconds: case.3,
nanos: case.4,
Expand Down
16 changes: 13 additions & 3 deletions prost-types/src/timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ impl Timestamp {
}
}

/// Return a normalized copy of the timestamp to a canonical format.
///
/// Based on [`google::protobuf::util::CreateNormalized`][1].
///
/// [1]: https://github.com/google/protobuf/blob/v3.3.2/src/google/protobuf/util/time_util.cc#L59-L77
pub fn normalized(&self) -> Self {
let mut result = *self;
result.normalize();
result
}

/// Creates a new `Timestamp` at the start of the provided UTC date.
pub fn date(year: i64, month: u8, day: u8) -> Result<Timestamp, TimestampError> {
Timestamp::date_time_nanos(year, month, day, 0, 0, 0, 0)
Expand Down Expand Up @@ -399,14 +410,13 @@ mod tests {
];

for case in cases.iter() {
let mut test_timestamp = crate::Timestamp {
let test_timestamp = crate::Timestamp {
seconds: case.1,
nanos: case.2,
};
test_timestamp.normalize();

assert_eq!(
test_timestamp,
test_timestamp.normalized(),
crate::Timestamp {
seconds: case.3,
nanos: case.4,
Expand Down

0 comments on commit 8d4cac5

Please sign in to comment.