1use std::os::unix::fs::MetadataExt;
7
8const NANOS_PER_SEC: i64 = 1_000_000_000;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct BackingStamp {
16 pub size: u64,
17 pub mtime_ns: i64,
18 pub ctime_ns: i64,
19}
20
21impl BackingStamp {
22 pub fn from_metadata(meta: &std::fs::Metadata) -> BackingStamp {
23 BackingStamp {
24 size: meta.len(),
25 mtime_ns: meta
26 .mtime()
27 .saturating_mul(NANOS_PER_SEC)
28 .saturating_add(meta.mtime_nsec()),
29 ctime_ns: meta
30 .ctime()
31 .saturating_mul(NANOS_PER_SEC)
32 .saturating_add(meta.ctime_nsec()),
33 }
34 }
35
36 pub fn from_track(t: &musefs_db::Track) -> BackingStamp {
37 BackingStamp {
38 size: t.backing_size,
39 mtime_ns: t.backing_mtime_ns,
40 ctime_ns: t.backing_ctime_ns,
41 }
42 }
43
44 pub fn display_secs(&self) -> i64 {
47 self.mtime_ns / NANOS_PER_SEC
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use std::os::unix::fs::MetadataExt;
55
56 #[test]
57 fn from_metadata_captures_ns_and_display_secs() {
58 let dir = tempfile::tempdir().unwrap();
59 let p = dir.path().join("f");
60 std::fs::write(&p, b"hello").unwrap();
61 let meta = std::fs::metadata(&p).unwrap();
62
63 let s = BackingStamp::from_metadata(&meta);
64 assert_eq!(s.size, 5);
65 assert_eq!(s.mtime_ns, meta.mtime() * 1_000_000_000 + meta.mtime_nsec());
66 assert_eq!(s.ctime_ns, meta.ctime() * 1_000_000_000 + meta.ctime_nsec());
67 assert_eq!(s.display_secs(), meta.mtime());
69 }
70
71 #[test]
72 fn equality_is_field_wise() {
73 let a = BackingStamp {
74 size: 1,
75 mtime_ns: 2,
76 ctime_ns: 3,
77 };
78 assert_eq!(
79 a,
80 BackingStamp {
81 size: 1,
82 mtime_ns: 2,
83 ctime_ns: 3
84 }
85 );
86 assert_ne!(
87 a,
88 BackingStamp {
89 size: 1,
90 mtime_ns: 2,
91 ctime_ns: 4
92 }
93 );
94 }
95}