@@ -19,18 +19,18 @@ use sha2::{Digest, Sha256, Sha256VarCore};
19
19
#[ allow( unused_imports) ]
20
20
use xxhash_rust:: xxh3:: xxh3_64;
21
21
22
- use std:: env;
23
22
use std:: fs:: * ;
24
23
use std:: io;
25
- use std:: io:: { Read , Write } ;
24
+ use std:: io:: { Read , Write } ;
26
25
#[ allow( unused_imports) ]
27
26
use std:: path:: { Path , PathBuf } ;
28
27
use std:: sync:: { Arc , Mutex } ;
29
- use std:: time:: { Duration , Instant } ;
30
-
28
+ use std:: time:: { Duration , Instant , UNIX_EPOCH } ;
29
+ use std:: { env, fs} ;
30
+ use chrono:: { DateTime , Local } ;
31
+ use serde:: Serialize ;
31
32
#[ allow( unused_imports) ]
32
33
use serde_json:: { json, Value } ;
33
- use serde:: Serialize ;
34
34
35
35
/// Simple path processor
36
36
#[ derive( Parser , Debug ) ]
@@ -50,16 +50,20 @@ struct Args {
50
50
struct FileRecordSha256 {
51
51
file : String ,
52
52
hash : Output < Sha256VarCore > ,
53
+ timestamp_mod : FileRecordsTimestamps ,
54
+ // timestamp_cre: FileRecordsTimestamps,
53
55
}
54
56
55
57
#[ derive( Clone , Debug , Eq , Ord , PartialEq , PartialOrd , Serialize ) ]
56
58
#[ allow( dead_code) ]
57
59
struct FileRecordXxhash {
58
60
file : String ,
59
- hash : u64
61
+ hash : u64 ,
62
+ timestamp_mod : FileRecordsTimestamps ,
63
+ // timestamp_cre: FileRecordsTimestamps,
60
64
}
61
65
62
- #[ derive( Serialize ) ]
66
+ #[ derive( Serialize , Debug , Clone , Eq , Ord , PartialEq , PartialOrd ) ]
63
67
struct FileRecordsTimestamps {
64
68
epoch : u128 ,
65
69
iso8601 : String ,
@@ -93,7 +97,7 @@ fn visit(path: &Path, cb: &mut dyn FnMut(PathBuf), exclude: Vec<&str>) -> io::Re
93
97
// Only include files that don't have a component in the exclude vector
94
98
// logic from: https://stackoverflow.com/a/29504547
95
99
let match_count = components
96
- . iter ( )
100
+ . par_iter ( )
97
101
. filter ( |& x| exclude. contains ( & x. to_str ( ) . unwrap ( ) ) )
98
102
. count ( ) ;
99
103
if match_count == 0 {
@@ -142,7 +146,8 @@ fn main() {
142
146
143
147
// To switch from Sha256 <-> Xxhash: 4 steps - #2: Set res to the right output
144
148
// let res: Result<(&str, Output<Sha256VarCore>), bool> = match f2 { // Sha256
145
- let res: Result < ( & str , u64 ) , bool > = match f2 { // xxhash
149
+ let res: Result < ( & str , u64 ) , bool > = match f2 {
150
+ // xxhash
146
151
#[ allow( unused_mut) ]
147
152
Ok ( mut f2) => {
148
153
// To switch from Sha256 <-> Xxhash: 4 steps - #3: Change the implementation block
@@ -165,20 +170,22 @@ fn main() {
165
170
166
171
// Save full path?
167
172
// Working relative path
168
- let filename = <PathBuf as AsRef < Path > >:: as_ref ( f) . to_str ( ) . unwrap_or_default ( ) ;
173
+ let filename = <PathBuf as AsRef < Path > >:: as_ref ( & f)
174
+ . to_str ( )
175
+ . unwrap_or_default ( ) ;
169
176
// Convert to absolute path
170
177
// let filenameref = <PathBuf as AsRef<Path>>::as_ref(f);
171
178
// let filename = filenameref.clone().canonicalize().unwrap().to_str().unwrap_or_default();
172
- // .clone().canonicalize().unwrap().to_str().unwrap_or_default();
179
+ // .clone().canonicalize().unwrap().to_str().unwrap_or_default();
173
180
// let fullpath = Path::new(filename.to_owned().as_str()).canonicalize().unwrap().to_str().unwrap_or_default();
174
181
// TODO: Fix check for save_full_path argument
175
182
// if args.safe_full;path {
176
- // Result::Ok((Path::new(fullpath.clone()).clone().canonicalize().unwrap().to_str().unwrap(),
177
- // xxhash_rust::xxh3::xxh3_64(&buffer)))
178
- // Result::Ok((filename, xxhash_rust::xxh3::xxh3_64(&buffer)))
183
+ // Result::Ok((Path::new(fullpath.clone()).clone().canonicalize().unwrap().to_str().unwrap(),
184
+ // xxhash_rust::xxh3::xxh3_64(&buffer)))
185
+ // Result::Ok((filename, xxhash_rust::xxh3::xxh3_64(&buffer)))
179
186
//
180
187
// } else { // Only save relative path
181
- Result :: Ok ( ( filename, xxhash_rust:: xxh3:: xxh3_64 ( & buffer) ) )
188
+ Result :: Ok ( ( filename, xxhash_rust:: xxh3:: xxh3_64 ( & buffer) ) )
182
189
// }
183
190
}
184
191
Err ( ref e) => {
@@ -187,45 +194,67 @@ fn main() {
187
194
}
188
195
} ;
189
196
if res. is_ok ( ) {
190
- // Create a new struct instance and populate with filename and filehash
191
- // To switch from Sha256 <-> Xxhash: 4 steps - #4: Change the record hash impl
192
- // Sha256
193
- // let frs = FileRecordSha256 {
194
- // filename: res.unwrap().0.to_owned(),
195
- // filehash: res.unwrap().1,
196
- // };
197
- // filelist.lock().unwrap().push(frs);
197
+ let metadata =
198
+ fs:: metadata ( res. unwrap ( ) . 0 ) . expect ( "Unable to get metadata for file: @203" ) ;
199
+ if let Ok ( modtime) = metadata. modified ( ) {
200
+ let modtimemillis = modtime. duration_since ( UNIX_EPOCH ) . unwrap ( ) . as_millis ( ) ;
201
+ // let cretimemillis = metadata.created().unwrap().duration_since(UNIX_EPOCH).unwrap().as_millis();
202
+ // Create a new struct instance and populate with filename and filehash
203
+ // To switch from Sha256 <-> Xxhash: 4 steps - #4: Change the record hash impl
204
+ // Sha256
205
+ // let frs = FileRecordSha256 {
206
+ // filename: res.unwrap().0.to_owned(),
207
+ // filehash: res.unwrap().1,
208
+ // timestamp_mod: FileRecordsTimestamps {
209
+ // epoch: time.duration_since(UNIX_EPOCH).unwrap().as_millis(),
210
+ // iso8601: DateTime::from_timestamp_millis(time.duration_since(UNIX_EPOCH).unwrap().as_millis() as i64).expect("Unable to parse timestamp").to_rfc3339(),
211
+ // },
212
+ // };
213
+ // filelist.lock().unwrap().push(frs);
214
+
215
+ // Xxhash
198
216
199
- // Xxhash
200
- let frs = FileRecordXxhash {
201
- file : res. unwrap ( ) . 0 . to_owned ( ) ,
202
- hash : res. unwrap ( ) . 1 ,
203
- } ;
204
- filelist. lock ( ) . unwrap ( ) . push ( frs) ;
217
+ let frs = FileRecordXxhash {
218
+ file : res. unwrap ( ) . 0 . to_owned ( ) ,
219
+ hash : res. unwrap ( ) . 1 ,
220
+ timestamp_mod : FileRecordsTimestamps {
221
+ epoch : modtimemillis,
222
+ iso8601 : DateTime :: from_timestamp_millis ( modtimemillis as i64 ) . expect ( "Unable to parse timestamp" ) . with_timezone ( & Local :: now ( ) . timezone ( ) ) . to_rfc3339 ( ) ,
223
+ } ,
224
+ // timestamp_cre: FileRecordsTimestamps {
225
+ // epoch: cretimemillis,
226
+ // iso8601: DateTime::from_timestamp_millis(cretimemillis as i64).expect("Unable to parse timestamp").with_timezone(&Local::now().timezone()).to_rfc3339(),
227
+ // },
228
+ } ;
229
+ filelist. lock ( ) . unwrap ( ) . push ( frs) ;
230
+ }
205
231
}
206
232
} ) ;
207
233
208
234
// Now sort and print vector (filelist)
209
235
// TODO: Avoid creating a new variable to hold the list
210
236
let mut fls2 = filelist. lock ( ) . unwrap ( ) . to_vec ( ) ;
211
237
fls2. sort ( ) ; // It just works!
212
- let path_info = PathInfo {
238
+ let path_info = PathInfo {
213
239
base : path. canonicalize ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_owned ( ) ,
214
240
cmdline : args. path . clone ( ) ,
215
- run_from : env:: current_dir ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_owned ( )
241
+ run_from : env:: current_dir ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . to_owned ( ) ,
216
242
} ;
217
243
let file_record: FileRecordsXxhash = FileRecordsXxhash {
218
244
path : path_info,
219
245
updated_on : get_time ( ) . unwrap ( ) ,
220
246
count : fls2. len ( ) ,
221
- files : fls2. clone ( )
247
+ files : fls2. clone ( ) ,
222
248
} ;
223
249
let file_record_json = serde_json:: to_string ( & file_record) . unwrap ( ) ;
224
250
// for i2 in fls2.iter() {
225
251
// println!("{:?} == {:x}", i2.filename, i2.filehash);
226
252
// }
227
253
228
- File :: create ( args. output ) . unwrap ( ) . write_all ( file_record_json. as_bytes ( ) ) . unwrap ( ) ;
254
+ File :: create ( args. output )
255
+ . unwrap ( )
256
+ . write_all ( file_record_json. as_bytes ( ) )
257
+ . unwrap ( ) ;
229
258
230
259
let dur: Duration = start. elapsed ( ) ; // End timer
231
260
eprintln ! ( "Time elapsed: {:?}" , dur) ; // Show elapsed time to STDERR
@@ -235,8 +264,8 @@ fn get_time() -> Result<FileRecordsTimestamps, std::io::Error> {
235
264
use std:: time:: { SystemTime , UNIX_EPOCH } ;
236
265
237
266
/* std::time attempt - can't format rfc3339 :(
238
- so switched to chrono
239
- */
267
+ so switched to chrono
268
+ */
240
269
// let start = SystemTime::now();
241
270
// let since_epoch = start
242
271
// .duration_since(UNIX_EPOCH)
@@ -247,10 +276,13 @@ fn get_time() -> Result<FileRecordsTimestamps, std::io::Error> {
247
276
// // (SystemTime::duration_from_millis(since_epoch).to_rfc3339()).to_string(),
248
277
// })
249
278
250
- use chrono:: { Local } ;
279
+ use chrono:: Local ;
251
280
252
281
Ok ( FileRecordsTimestamps {
253
- epoch : SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) . as_millis ( ) ,
282
+ epoch : SystemTime :: now ( )
283
+ . duration_since ( UNIX_EPOCH )
284
+ . unwrap ( )
285
+ . as_millis ( ) ,
254
286
iso8601 : Local :: now ( ) . to_rfc3339 ( ) ,
255
287
} )
256
288
}
0 commit comments