]> git.proxmox.com Git - rustc.git/blame - src/vendor/filetime/src/lib.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / filetime / src / lib.rs
CommitLineData
476ff2be
SL
1//! Timestamps for files in Rust
2//!
3//! This library provides platform-agnostic inspection of the various timestamps
4//! present in the standard `fs::Metadata` structure.
5//!
6//! # Installation
7//!
ea8adc8c 8//! Add this to your `Cargo.toml`:
476ff2be
SL
9//!
10//! ```toml
11//! [dependencies]
12//! filetime = "0.1"
13//! ```
14//!
15//! # Usage
16//!
17//! ```no_run
18//! use std::fs;
19//! use filetime::FileTime;
20//!
21//! let metadata = fs::metadata("foo.txt").unwrap();
22//!
23//! let mtime = FileTime::from_last_modification_time(&metadata);
24//! println!("{}", mtime);
25//!
26//! let atime = FileTime::from_last_access_time(&metadata);
27//! assert!(mtime < atime);
28//!
29//! // Inspect values that can be interpreted across platforms
30//! println!("{}", mtime.seconds_relative_to_1970());
31//! println!("{}", mtime.nanoseconds());
32//!
33//! // Print the platform-specific value of seconds
34//! println!("{}", mtime.seconds());
35//! ```
36
abe05a73
XL
37#[macro_use]
38extern crate cfg_if;
39
476ff2be
SL
40use std::fmt;
41use std::fs;
42use std::io;
43use std::path::Path;
44
abe05a73
XL
45cfg_if! {
46 if #[cfg(target_os = "redox")] {
47 #[path = "redox.rs"]
48 mod imp;
49 } else if #[cfg(windows)] {
50 #[path = "windows.rs"]
51 mod imp;
52 } else {
53 #[path = "unix/mod.rs"]
54 mod imp;
55 }
56}
ea8adc8c 57
476ff2be
SL
58/// A helper structure to represent a timestamp for a file.
59///
60/// The actual value contined within is platform-specific and does not have the
61/// same meaning across platforms, but comparisons and stringification can be
62/// significant among the same platform.
63#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone, Hash)]
64pub struct FileTime {
65 seconds: u64,
66 nanos: u32,
67}
68
69impl FileTime {
70 /// Creates a new timestamp representing a 0 time.
71 ///
72 /// Useful for creating the base of a cmp::max chain of times.
73 pub fn zero() -> FileTime {
74 FileTime { seconds: 0, nanos: 0 }
75 }
76
77 /// Creates a new instance of `FileTime` with a number of seconds and
78 /// nanoseconds relative to January 1, 1970.
79 ///
80 /// Note that this is typically the relative point that Unix time stamps are
81 /// from, but on Windows the native time stamp is relative to January 1,
82 /// 1601 so the return value of `seconds` from the returned `FileTime`
83 /// instance may not be the same as that passed in.
84 pub fn from_seconds_since_1970(seconds: u64, nanos: u32) -> FileTime {
85 FileTime {
86 seconds: seconds + if cfg!(windows) {11644473600} else {0},
87 nanos: nanos,
88 }
89 }
90
91 /// Creates a new timestamp from the last modification time listed in the
92 /// specified metadata.
93 ///
94 /// The returned value corresponds to the `mtime` field of `stat` on Unix
95 /// platforms and the `ftLastWriteTime` field on Windows platforms.
96 pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
ea8adc8c 97 imp::from_last_modification_time(meta)
476ff2be
SL
98 }
99
100 /// Creates a new timestamp from the last access time listed in the
101 /// specified metadata.
102 ///
103 /// The returned value corresponds to the `atime` field of `stat` on Unix
104 /// platforms and the `ftLastAccessTime` field on Windows platforms.
105 pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
ea8adc8c 106 imp::from_last_access_time(meta)
476ff2be
SL
107 }
108
109 /// Creates a new timestamp from the creation time listed in the specified
110 /// metadata.
111 ///
112 /// The returned value corresponds to the `birthtime` field of `stat` on
113 /// Unix platforms and the `ftCreationTime` field on Windows platforms. Note
114 /// that not all Unix platforms have this field available and may return
115 /// `None` in some circumstances.
116 pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
ea8adc8c 117 imp::from_creation_time(meta)
476ff2be
SL
118 }
119
120 /// Returns the whole number of seconds represented by this timestamp.
121 ///
122 /// Note that this value's meaning is **platform specific**. On Unix
123 /// platform time stamps are typically relative to January 1, 1970, but on
124 /// Windows platforms time stamps are relative to January 1, 1601.
125 pub fn seconds(&self) -> u64 { self.seconds }
126
127 /// Returns the whole number of seconds represented by this timestamp,
128 /// relative to the Unix epoch start of January 1, 1970.
129 ///
130 /// Note that this does not return the same value as `seconds` for Windows
131 /// platforms as seconds are relative to a different date there.
132 pub fn seconds_relative_to_1970(&self) -> u64 {
133 self.seconds - if cfg!(windows) {11644473600} else {0}
134 }
135
136 /// Returns the nanosecond precision of this timestamp.
137 ///
138 /// The returned value is always less than one billion and represents a
139 /// portion of a second forward from the seconds returned by the `seconds`
140 /// method.
141 pub fn nanoseconds(&self) -> u32 { self.nanos }
142}
143
144impl fmt::Display for FileTime {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 write!(f, "{}.{:09}s", self.seconds, self.nanos)
147 }
148}
149
150/// Set the last access and modification times for a file on the filesystem.
151///
152/// This function will set the `atime` and `mtime` metadata fields for a file
153/// on the local filesystem, returning any error encountered.
154pub fn set_file_times<P>(p: P, atime: FileTime, mtime: FileTime)
ea8adc8c
XL
155 -> io::Result<()>
156 where P: AsRef<Path>
157{
158 imp::set_file_times(p.as_ref(), atime, mtime)
476ff2be
SL
159}
160
ea8adc8c
XL
161/// Set the last access and modification times for a file on the filesystem.
162/// This function does not follow symlink.
163///
164/// This function will set the `atime` and `mtime` metadata fields for a file
165/// on the local filesystem, returning any error encountered.
166pub fn set_symlink_file_times<P>(p: P, atime: FileTime, mtime: FileTime)
167 -> io::Result<()>
168 where P: AsRef<Path>
169{
170 imp::set_symlink_file_times(p.as_ref(), atime, mtime)
476ff2be
SL
171}
172
173#[cfg(test)]
174mod tests {
175 extern crate tempdir;
176
ea8adc8c
XL
177 use std::io;
178 use std::path::Path;
476ff2be
SL
179 use std::fs::{self, File};
180 use self::tempdir::TempDir;
ea8adc8c
XL
181 use super::{FileTime, set_file_times, set_symlink_file_times};
182
183 #[cfg(unix)]
184 fn make_symlink<P,Q>(src: P, dst: Q) -> io::Result<()>
185 where P: AsRef<Path>,
186 Q: AsRef<Path>,
187 {
188 use std::os::unix::fs::symlink;
189 symlink(src, dst)
190 }
191
192 #[cfg(windows)]
193 fn make_symlink<P,Q>(src: P, dst: Q) -> io::Result<()>
194 where P: AsRef<Path>,
195 Q: AsRef<Path>,
196 {
197 use std::os::windows::fs::symlink_file;
198 symlink_file(src, dst)
199 }
476ff2be
SL
200
201 #[test]
202 fn set_file_times_test() {
203 let td = TempDir::new("filetime").unwrap();
204 let path = td.path().join("foo.txt");
205 File::create(&path).unwrap();
206
207 let metadata = fs::metadata(&path).unwrap();
208 let mtime = FileTime::from_last_modification_time(&metadata);
209 let atime = FileTime::from_last_access_time(&metadata);
210 set_file_times(&path, atime, mtime).unwrap();
211
212 let new_mtime = FileTime::from_seconds_since_1970(10_000, 0);
213 set_file_times(&path, atime, new_mtime).unwrap();
214
215 let metadata = fs::metadata(&path).unwrap();
216 let mtime = FileTime::from_last_modification_time(&metadata);
217 assert_eq!(mtime, new_mtime);
ea8adc8c
XL
218
219 let spath = td.path().join("bar.txt");
220 make_symlink(&path, &spath).unwrap();
221 let metadata = fs::symlink_metadata(&spath).unwrap();
222 let smtime = FileTime::from_last_modification_time(&metadata);
223
224 set_file_times(&spath, atime, mtime).unwrap();
225
226 let metadata = fs::metadata(&path).unwrap();
227 let cur_mtime = FileTime::from_last_modification_time(&metadata);
228 assert_eq!(mtime, cur_mtime);
229
230 let metadata = fs::symlink_metadata(&spath).unwrap();
231 let cur_mtime = FileTime::from_last_modification_time(&metadata);
232 assert_eq!(smtime, cur_mtime);
233
234 set_file_times(&spath, atime, new_mtime).unwrap();
235
236 let metadata = fs::metadata(&path).unwrap();
237 let mtime = FileTime::from_last_modification_time(&metadata);
238 assert_eq!(mtime, new_mtime);
239
240 let metadata = fs::symlink_metadata(&spath).unwrap();
241 let mtime = FileTime::from_last_modification_time(&metadata);
242 assert_eq!(mtime, smtime);
243 }
244
245 #[test]
246 fn set_symlink_file_times_test() {
247 let td = TempDir::new("filetime").unwrap();
248 let path = td.path().join("foo.txt");
249 File::create(&path).unwrap();
250
251 let metadata = fs::metadata(&path).unwrap();
252 let mtime = FileTime::from_last_modification_time(&metadata);
253 let atime = FileTime::from_last_access_time(&metadata);
254 set_symlink_file_times(&path, atime, mtime).unwrap();
255
256 let new_mtime = FileTime::from_seconds_since_1970(10_000, 0);
257 set_symlink_file_times(&path, atime, new_mtime).unwrap();
258
259 let metadata = fs::metadata(&path).unwrap();
260 let mtime = FileTime::from_last_modification_time(&metadata);
261 assert_eq!(mtime, new_mtime);
262
263 let spath = td.path().join("bar.txt");
264 make_symlink(&path, &spath).unwrap();
265
266 let metadata = fs::symlink_metadata(&spath).unwrap();
267 let smtime = FileTime::from_last_modification_time(&metadata);
268 let satime = FileTime::from_last_access_time(&metadata);
269 set_symlink_file_times(&spath, smtime, satime).unwrap();
270
271 let metadata = fs::metadata(&path).unwrap();
272 let mtime = FileTime::from_last_modification_time(&metadata);
273 assert_eq!(mtime, new_mtime);
274
275 let new_smtime = FileTime::from_seconds_since_1970(20_000, 0);
276 set_symlink_file_times(&spath, atime, new_smtime).unwrap();
277
278 let metadata = fs::metadata(&spath).unwrap();
279 let mtime = FileTime::from_last_modification_time(&metadata);
280 assert_eq!(mtime, new_mtime);
281
282 let metadata = fs::symlink_metadata(&spath).unwrap();
283 let mtime = FileTime::from_last_modification_time(&metadata);
284 assert_eq!(mtime, new_smtime);
476ff2be
SL
285 }
286}