1#[cfg(test)]
2use crate::system::file_time_now;
3
4#[derive(Copy, Clone, Debug, Eq, PartialEq, Default, get_size2::GetSize)]
14pub struct FileRevision(u128);
15
16impl FileRevision {
17 pub fn new(value: u128) -> Self {
18 Self(value)
19 }
20
21 pub(crate) const fn zero() -> Self {
22 Self(0)
23 }
24
25 #[must_use]
26 pub(crate) fn as_u128(self) -> u128 {
27 self.0
28 }
29}
30
31impl From<u128> for FileRevision {
32 fn from(value: u128) -> Self {
33 FileRevision(value)
34 }
35}
36
37impl From<u64> for FileRevision {
38 fn from(value: u64) -> Self {
39 FileRevision(u128::from(value))
40 }
41}
42
43impl From<filetime::FileTime> for FileRevision {
44 fn from(value: filetime::FileTime) -> Self {
45 let seconds = value.seconds() as u128;
46 let seconds = seconds << 64;
47 let nanos = u128::from(value.nanoseconds());
48
49 FileRevision(seconds | nanos)
50 }
51}
52
53#[cfg(test)]
54mod tests {
55
56 use super::*;
57
58 #[test]
59 fn revision_from_file_time() {
60 let file_time = file_time_now();
61 let revision = FileRevision::from(file_time);
62
63 let revision = revision.as_u128();
64
65 let nano = revision & 0xFFFF_FFFF_FFFF_FFFF;
66 let seconds = revision >> 64;
67
68 assert_eq!(file_time.nanoseconds(), nano as u32);
69 assert_eq!(file_time.seconds(), seconds as i64);
70 }
71}