From efe7d627f5e9a1a585006d181dfc135724df5b2d Mon Sep 17 00:00:00 2001 From: "Guillaume W. Bres" Date: Sun, 6 Nov 2022 17:41:43 +0100 Subject: [PATCH 1/3] epoch: derive Hash Hash is required if we want structures like "HashMap" or "BTreeMap" indexed by an `Epoch` Signed-off-by: Guillaume W. Bres --- src/duration.rs | 2 +- src/epoch.rs | 2 +- src/timescale.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/duration.rs b/src/duration.rs index 45b909cf..489ad518 100644 --- a/src/duration.rs +++ b/src/duration.rs @@ -53,7 +53,7 @@ pub const NANOSECONDS_PER_CENTURY: u64 = DAYS_PER_CENTURY_U64 * NANOSECONDS_PER_ /// That difference is exactly 1 nanoseconds, where the former duration is "closer to zero" than the latter. /// As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY. /// 2. It was also decided that opposite durations are equal, e.g. -15 minutes == 15 minutes. If the direction of time matters, use the signum function. -#[derive(Clone, Copy, Debug, PartialOrd, Eq, Ord)] +#[derive(Clone, Copy, Debug, PartialOrd, Eq, Ord, Hash)] #[repr(C)] #[cfg_attr(feature = "python", pyclass)] pub struct Duration { diff --git a/src/epoch.rs b/src/epoch.rs index 987edbb1..c48c71fd 100644 --- a/src/epoch.rs +++ b/src/epoch.rs @@ -155,7 +155,7 @@ const CUMULATIVE_DAYS_FOR_MONTH: [u16; 12] = { /// Defines a nanosecond-precision Epoch. /// /// Refer to the appropriate functions for initializing this Epoch from different time systems or representations. -#[derive(Copy, Clone, Eq)] +#[derive(Copy, Clone, Eq, Hash)] #[repr(C)] #[cfg_attr(feature = "python", pyclass)] pub struct Epoch { diff --git a/src/timescale.rs b/src/timescale.rs index 83041b7b..c7e194c4 100644 --- a/src/timescale.rs +++ b/src/timescale.rs @@ -52,7 +52,7 @@ pub const UNIX_REF_EPOCH: Epoch = Epoch::from_tai_duration(Duration { }); /// Enum of the different time systems available -#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "python", pyclass)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum TimeScale { From 0d246ad9f7bb94e2674406fe0c708ce5a3ee769b Mon Sep 17 00:00:00 2001 From: "Guillaume W. Bres" Date: Sun, 6 Nov 2022 18:32:49 +0100 Subject: [PATCH 2/3] epoch: derive Hash Implement Hash ourselves so it is consistent with PartialEq Signed-off-by: Guillaume W. Bres --- src/duration.rs | 10 +++++++++- src/epoch.rs | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/duration.rs b/src/duration.rs index 489ad518..fc12d788 100644 --- a/src/duration.rs +++ b/src/duration.rs @@ -19,6 +19,7 @@ use core::cmp::Ordering; use core::convert::TryInto; use core::fmt; use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; +use core::hash::{Hash, Hasher}; #[cfg(feature = "std")] use serde::{de, Deserialize, Deserializer}; @@ -53,7 +54,7 @@ pub const NANOSECONDS_PER_CENTURY: u64 = DAYS_PER_CENTURY_U64 * NANOSECONDS_PER_ /// That difference is exactly 1 nanoseconds, where the former duration is "closer to zero" than the latter. /// As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY. /// 2. It was also decided that opposite durations are equal, e.g. -15 minutes == 15 minutes. If the direction of time matters, use the signum function. -#[derive(Clone, Copy, Debug, PartialOrd, Eq, Ord, Hash)] +#[derive(Clone, Copy, Debug, PartialOrd, Eq, Ord)] #[repr(C)] #[cfg_attr(feature = "python", pyclass)] pub struct Duration { @@ -82,6 +83,13 @@ impl PartialEq for Duration { } } +impl Hash for Duration { + fn hash(&self, hasher: &mut H) { + self.centuries.hash(hasher); + self.nanoseconds.hash(hasher); + } +} + impl Default for Duration { fn default() -> Self { Duration::ZERO diff --git a/src/epoch.rs b/src/epoch.rs index c48c71fd..780a7bb6 100644 --- a/src/epoch.rs +++ b/src/epoch.rs @@ -17,6 +17,7 @@ use crate::{ }; use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use core::fmt; +use core::hash::{Hash, Hasher}; use core::ops::{Add, AddAssign, Sub, SubAssign}; use crate::ParsingErrors; @@ -155,7 +156,7 @@ const CUMULATIVE_DAYS_FOR_MONTH: [u16; 12] = { /// Defines a nanosecond-precision Epoch. /// /// Refer to the appropriate functions for initializing this Epoch from different time systems or representations. -#[derive(Copy, Clone, Eq, Hash)] +#[derive(Copy, Clone, Eq)] #[repr(C)] #[cfg_attr(feature = "python", pyclass)] pub struct Epoch { @@ -250,6 +251,12 @@ impl PartialEq for Epoch { } } +impl Hash for Epoch { + fn hash(&self, hasher: &mut H) { + self.duration_since_j1900_tai.hash(hasher); + } +} + impl PartialOrd for Epoch { fn partial_cmp(&self, other: &Self) -> Option { Some( From 0a1b05d86223109f86788ce0a2d81476db51f57b Mon Sep 17 00:00:00 2001 From: Christopher Rabotin Date: Sun, 6 Nov 2022 13:23:31 -0700 Subject: [PATCH 3/3] Cargo fmt --- src/duration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/duration.rs b/src/duration.rs index fc12d788..9f01bfe8 100644 --- a/src/duration.rs +++ b/src/duration.rs @@ -18,8 +18,8 @@ extern crate core; use core::cmp::Ordering; use core::convert::TryInto; use core::fmt; -use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; use core::hash::{Hash, Hasher}; +use core::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; #[cfg(feature = "std")] use serde::{de, Deserialize, Deserializer};