rust/hg-core/src/dirstate_tree/on_disk.rs
changeset 48191 a5a673ec8f6f
parent 48190 0cc0c0972164
child 48192 d2f760c2c91c
equal deleted inserted replaced
48190:0cc0c0972164 48191:a5a673ec8f6f
   124 pub(super) struct Timestamp {
   124 pub(super) struct Timestamp {
   125     seconds: I64Be,
   125     seconds: I64Be,
   126 
   126 
   127     /// In `0 .. 1_000_000_000`.
   127     /// In `0 .. 1_000_000_000`.
   128     ///
   128     ///
   129     /// This timestamp is later or earlier than `(seconds, 0)` by this many
   129     /// This timestamp is after `(seconds, 0)` by this many nanoseconds.
   130     /// nanoseconds, if `seconds` is non-negative or negative, respectively.
       
   131     nanoseconds: U32Be,
   130     nanoseconds: U32Be,
   132 }
   131 }
   133 
   132 
   134 /// Counted in bytes from the start of the file
   133 /// Counted in bytes from the start of the file
   135 ///
   134 ///
   444     }
   443     }
   445 }
   444 }
   446 
   445 
   447 impl From<SystemTime> for Timestamp {
   446 impl From<SystemTime> for Timestamp {
   448     fn from(system_time: SystemTime) -> Self {
   447     fn from(system_time: SystemTime) -> Self {
       
   448         // On Unix, `SystemTime` is a wrapper for the `timespec` C struct:
       
   449         // https://www.gnu.org/software/libc/manual/html_node/Time-Types.html#index-struct-timespec
       
   450         // We want to effectively access its fields, but the Rust standard
       
   451         // library does not expose them. The best we can do is:
   449         let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) {
   452         let (secs, nanos) = match system_time.duration_since(UNIX_EPOCH) {
   450             Ok(duration) => {
   453             Ok(duration) => {
   451                 (duration.as_secs() as i64, duration.subsec_nanos())
   454                 (duration.as_secs() as i64, duration.subsec_nanos())
   452             }
   455             }
   453             Err(error) => {
   456             Err(error) => {
       
   457                 // `system_time` is before `UNIX_EPOCH`.
       
   458                 // We need to undo this algorithm:
       
   459                 // https://github.com/rust-lang/rust/blob/6bed1f0bc3cc50c10aab26d5f94b16a00776b8a5/library/std/src/sys/unix/time.rs#L40-L41
   454                 let negative = error.duration();
   460                 let negative = error.duration();
   455                 (-(negative.as_secs() as i64), negative.subsec_nanos())
   461                 let negative_secs = negative.as_secs() as i64;
       
   462                 let negative_nanos = negative.subsec_nanos();
       
   463                 if negative_nanos == 0 {
       
   464                     (-negative_secs, 0)
       
   465                 } else {
       
   466                     // For example if `system_time` was 4.3 seconds before
       
   467                     // the Unix epoch we get a Duration that represents
       
   468                     // `(-4, -0.3)` but we want `(-5, +0.7)`:
       
   469                     const NSEC_PER_SEC: u32 = 1_000_000_000;
       
   470                     (-1 - negative_secs, NSEC_PER_SEC - negative_nanos)
       
   471                 }
   456             }
   472             }
   457         };
   473         };
   458         Timestamp {
   474         Timestamp {
   459             seconds: secs.into(),
   475             seconds: secs.into(),
   460             nanoseconds: nanos.into(),
   476             nanoseconds: nanos.into(),