Skip to content

Commit

Permalink
feat(proto): Timestamp::from_milis() (#24)
Browse files Browse the repository at this point in the history
* build: upgrade to tenderdash v0.13.0-dev.1

* chore: formatting improvement to restart GHA

* feat(proto): Timestamp::from_milis()

* chore(proto): panic when timestamp millis out of range + tests

* chore: unify cargo.toml dependency code style
  • Loading branch information
lklimek authored Jul 20, 2023
1 parent b397f63 commit 00454db
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
8 changes: 4 additions & 4 deletions abci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ tracing-subscriber = { version = "0.3", optional = true, default-features = fals
"ansi",
"env-filter",
] }
thiserror = "1.0.39"
thiserror = { version = "1.0.39" }
url = { version = "2.3.1" }
semver = { version = "1.0.17" }
lhash = { version = "1.0.1", features = ["sha256"], optional = true }
Expand All @@ -56,9 +56,9 @@ tokio = { version = "1.28", features = [
futures = { version = "0.3.28", optional = true }

[dev-dependencies]
anyhow = "1.0.69"
bincode = "2.0.0-rc.2"
blake2 = "0.10.6"
anyhow = { version = "1.0.69" }
bincode = { version = "2.0.0-rc.2" }
blake2 = { version = "0.10.6" }
bollard = { version = "0.14.0" }
futures = { version = "0.3.26" }
tokio = { version = "1", features = ["macros", "signal", "time", "io-std"] }
Expand Down
79 changes: 77 additions & 2 deletions proto/src/serializers/timestamp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Serialize/deserialize Timestamp type from and into string:

use core::fmt;
use core::fmt::{self, Debug};

use serde::{de::Error as _, ser::Error, Deserialize, Deserializer, Serialize, Serializer};
use time::{
Expand Down Expand Up @@ -29,6 +29,16 @@ impl From<Rfc3339> for Timestamp {

pub trait ToMilis {
/// Convert protobuf timestamp into miliseconds since epoch

/// Note there is a resolution difference, as timestamp uses nanoseconds
///
/// # Arguments
///
/// * millis - time since epoch, in miliseconds
///
/// # Panics
///
/// Panics when timestamp doesn't fit `u64` type
fn to_milis(&self) -> u64;
}

Expand All @@ -37,7 +47,43 @@ impl ToMilis for Timestamp {
fn to_milis(&self) -> u64 {
chrono::NaiveDateTime::from_timestamp_opt(self.seconds, self.nanos as u32)
.unwrap()
.timestamp_millis() as u64
.timestamp_millis()
.try_into()
.expect("timestamp value out of u64 range")
}
}

pub trait FromMilis {
/// Create protobuf timestamp from miliseconds since epoch
///
/// Note there is a resolution difference, as timestamp uses nanoseconds
///
/// # Arguments
///
/// * millis - time since epoch, in miliseconds; must fit `i64` type
fn from_milis(millis: u64) -> Self;
}

impl FromMilis for Timestamp {
/// Create protobuf timestamp from miliseconds since epoch
///
/// Note there is a resolution difference, as timestamp uses nanoseconds
///
/// # Panics
///
/// Panics when `millis` don't fit `i64` type
fn from_milis(millis: u64) -> Self {
let dt = chrono::NaiveDateTime::from_timestamp_millis(
millis
.try_into()
.expect("milliseconds timestamp out of i64 range"),
)
.expect("cannot parse timestamp");

Self {
nanos: dt.timestamp_subsec_nanos() as i32,
seconds: dt.timestamp(),
}
}
}

Expand Down Expand Up @@ -207,4 +253,33 @@ mod test {
assert_eq!(json, serde_json::to_string(&rfc).unwrap());
}
}

#[test]
fn timestamp_from_to() {
let time_ms = 1687848809533;

let from = Timestamp::from_milis(time_ms);
let to = from.to_milis();

assert_eq!(to, time_ms);
}

#[test]
#[should_panic]
fn timestamp_millis_out_of_range() {
let time_ms = u64::MAX - 1;

let from = Timestamp::from_milis(time_ms);
}

#[test]
#[should_panic]
fn timestamp_negative() {
let ts = Timestamp {
nanos: 1000,
seconds: -12,
};

let to = ts.to_milis();
}
}

0 comments on commit 00454db

Please sign in to comment.