Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/dirstate/entry.rs @ 48204:d2f760c2c91c
dirstate-v2: Separate Rust structs for Timestamp and PackedTimestamp
PackedTimestamp is now exclusively for dirstate-v2 serialization purpose.
It contains unaligned big-endian integers. Timestamp is used everywhere else
and contains native Rust integers.
Differential Revision: https://phab.mercurial-scm.org/D11632
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Tue, 12 Oct 2021 16:20:05 +0200 |
parents | 1ab4523afe12 |
children | 320de901896a |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate/entry.rs Mon Oct 11 22:19:42 2021 +0200 +++ b/rust/hg-core/src/dirstate/entry.rs Tue Oct 12 16:20:05 2021 +0200 @@ -1,6 +1,7 @@ use crate::errors::HgError; use bitflags::bitflags; use std::convert::TryFrom; +use std::time::{SystemTime, UNIX_EPOCH}; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum EntryState { @@ -28,6 +29,73 @@ } } +#[derive(Copy, Clone, PartialEq)] +pub struct Timestamp { + seconds: i64, + + /// In `0 .. 1_000_000_000`. + /// + /// This timestamp is after `(seconds, 0)` by this many nanoseconds. + nanoseconds: u32, +} + +impl Timestamp { + pub fn new(seconds: i64, nanoseconds: u32) -> Self { + Self { + seconds, + nanoseconds, + } + } + + pub fn seconds(&self) -> i64 { + self.seconds + } + + pub fn nanoseconds(&self) -> u32 { + self.nanoseconds + } +} + +impl From<SystemTime> for Timestamp { + fn from(system_time: SystemTime) -> Self { + // On Unix, `SystemTime` is a wrapper for the `timespec` C struct: + // https://www.gnu.org/software/libc/manual/html_node/Time-Types.html#index-struct-timespec + // We want to effectively access its fields, but the Rust standard + // library does not expose them. The best we can do is: + let seconds; + let nanoseconds; + match system_time.duration_since(UNIX_EPOCH) { + Ok(duration) => { + seconds = duration.as_secs() as i64; + nanoseconds = duration.subsec_nanos(); + } + Err(error) => { + // `system_time` is before `UNIX_EPOCH`. + // We need to undo this algorithm: + // https://github.com/rust-lang/rust/blob/6bed1f0bc3cc50c10aab26d5f94b16a00776b8a5/library/std/src/sys/unix/time.rs#L40-L41 + let negative = error.duration(); + let negative_secs = negative.as_secs() as i64; + let negative_nanos = negative.subsec_nanos(); + if negative_nanos == 0 { + seconds = -negative_secs; + nanoseconds = 0; + } else { + // For example if `system_time` was 4.3 seconds before + // the Unix epoch we get a Duration that represents + // `(-4, -0.3)` but we want `(-5, +0.7)`: + const NSEC_PER_SEC: u32 = 1_000_000_000; + seconds = -1 - negative_secs; + nanoseconds = NSEC_PER_SEC - negative_nanos; + } + } + }; + Self { + seconds, + nanoseconds, + } + } +} + pub const V1_RANGEMASK: i32 = 0x7FFFFFFF; pub const MTIME_UNSET: i32 = -1;