11use std:: env;
22use std:: io:: { self , BufRead , BufReader , Write , BufWriter } ;
3+ use std:: path:: Path ;
34use std:: time:: { SystemTime , UNIX_EPOCH , Instant } ;
45use chrono:: { DateTime , Local , Utc , TimeZone , Timelike , Datelike } ;
56
@@ -38,13 +39,15 @@ impl Config {
3839 unbuffered : true ,
3940 timezone : None ,
4041 } ;
41-
42+
4243 let args: Vec < String > = env:: args ( ) . collect ( ) ;
44+ let program_name = Self :: get_program_name ( & args[ 0 ] ) ;
45+
4346 let mut i = 1 ;
4447 while i < args. len ( ) {
4548 match args[ i] . as_str ( ) {
4649 "-h" | "--help" => {
47- Self :: print_help ( ) ;
50+ Self :: print_help ( & program_name ) ;
4851 std:: process:: exit ( 0 ) ;
4952 }
5053 "-r" | "--relative" => config. relative = true ,
@@ -92,25 +95,33 @@ impl Config {
9295 }
9396 i += 1 ;
9497 }
95-
98+
9699 // Validation
97100 if config. microseconds && config. nanoseconds {
98101 eprintln ! ( "Error: Cannot use both --microseconds and --nanoseconds" ) ;
99102 std:: process:: exit ( 1 ) ;
100103 }
101-
102104 if config. relative && config. since_epoch {
103105 eprintln ! ( "Error: Cannot use both --relative and --epoch" ) ;
104106 std:: process:: exit ( 1 ) ;
105107 }
106-
108+
107109 Ok ( config)
108110 }
109-
110- fn print_help ( ) {
111+
112+ fn get_program_name ( argv0 : & str ) -> String {
113+ Path :: new ( argv0)
114+ . file_name ( )
115+ . and_then ( |name| name. to_str ( ) )
116+ . unwrap_or ( "ts" )
117+ . to_string ( )
118+ }
119+
120+ fn print_help ( program_name : & str ) {
111121 println ! (
112- "ts - timestamp each line of input
113- Usage: ts [OPTIONS]
122+ "{} - timestamp each line of input
123+
124+ Usage: {} [OPTIONS]
114125
115126Options:
116127 -f, --format FORMAT Date format (default: %Y-%m-%d %H:%M:%S)
@@ -136,16 +147,17 @@ Format specifiers (strftime compatible):
136147 %z Timezone offset %Z Timezone name %% Literal %
137148
138149Examples:
139- ls -la | ts # Basic timestamping
140- tail -f /var/log/messages | ts -r # Relative timestamps
141- ping google.com | ts -f \" [%H:%M:%S.%3f]\" # Custom format
142- dmesg | ts -i # ISO format
143- make 2>&1 | ts -e # Epoch timestamps
144- tail -f app.log | ts -r -m # Relative monotonic
145- cat file.txt | ts --delta # Show time between lines
146- ping host | ts --color --microseconds # Colored with microseconds
147- command | ts --prefix-only # Only timestamps
148- "
150+ ls -la | {} # Basic timestamping
151+ tail -f /var/log/messages | {} -r # Relative timestamps
152+ ping google.com | {} -f \" [%H:%M:%S.%3f]\" # Custom format
153+ dmesg | {} -i # ISO format
154+ make 2>&1 | {} -e # Epoch timestamps
155+ tail -f app.log | {} -r -m # Relative monotonic
156+ cat file.txt | {} --delta # Show time between lines
157+ ping host | {} --color --microseconds # Colored with microseconds
158+ command | {} --prefix-only # Only timestamps" ,
159+ program_name, program_name, program_name, program_name, program_name,
160+ program_name, program_name, program_name, program_name, program_name, program_name
149161 ) ;
150162 }
151163}
@@ -241,7 +253,7 @@ impl TimeFormatter {
241253 color : config. color ,
242254 }
243255 }
244-
256+
245257 #[ inline]
246258 fn format_timestamp ( & mut self , monotonic : bool ) -> & str {
247259 self . timestamp_buf . clear ( ) ;
@@ -252,12 +264,12 @@ impl TimeFormatter {
252264
253265 match & self . format_type {
254266 FormatType :: Delta => {
255- let now = if monotonic {
267+ let duration = if monotonic {
256268 let instant = Instant :: now ( ) ;
257269 let duration = if let Some ( last) = self . last_instant {
258270 instant. duration_since ( last)
259271 } else {
260- std:: time:: Duration :: from_secs ( 0 )
272+ std:: time:: Duration :: ZERO
261273 } ;
262274 self . last_instant = Some ( instant) ;
263275 duration
@@ -266,53 +278,53 @@ impl TimeFormatter {
266278 let duration = if let Some ( last) = self . last_time {
267279 time. duration_since ( last) . unwrap_or_default ( )
268280 } else {
269- std:: time:: Duration :: from_secs ( 0 )
281+ std:: time:: Duration :: ZERO
270282 } ;
271283 self . last_time = Some ( time) ;
272284 duration
273285 } ;
274286
275- let total_us = now . as_micros ( ) ;
287+ let total_us = duration . as_micros ( ) ;
276288 use std:: fmt:: Write ;
277- write ! ( self . timestamp_buf, "{}.{:06}" ,
278- total_us / 1_000_000 , total_us % 1_000_000 ) . unwrap ( ) ;
289+ let _ = write ! ( self . timestamp_buf, "{}.{:06}" ,
290+ total_us / 1_000_000 , total_us % 1_000_000 ) ;
279291 } ,
280292
281293 FormatType :: Epoch => {
282294 let now = SystemTime :: now ( ) ;
283295 let secs = now. duration_since ( UNIX_EPOCH ) . unwrap ( ) . as_secs ( ) ;
284296 use std:: fmt:: Write ;
285- write ! ( self . timestamp_buf, "{}" , secs) . unwrap ( ) ;
297+ let _ = write ! ( self . timestamp_buf, "{}" , secs) ;
286298 } ,
287299
288300 FormatType :: EpochUs => {
289301 let now = SystemTime :: now ( ) ;
290302 let us = now. duration_since ( UNIX_EPOCH ) . unwrap ( ) . as_micros ( ) ;
291303 use std:: fmt:: Write ;
292- write ! ( self . timestamp_buf, "{}" , us) . unwrap ( ) ;
304+ let _ = write ! ( self . timestamp_buf, "{}" , us) ;
293305 } ,
294306
295307 FormatType :: EpochNs => {
296308 let now = SystemTime :: now ( ) ;
297309 let ns = now. duration_since ( UNIX_EPOCH ) . unwrap ( ) . as_nanos ( ) ;
298310 use std:: fmt:: Write ;
299- write ! ( self . timestamp_buf, "{}" , ns) . unwrap ( ) ;
311+ let _ = write ! ( self . timestamp_buf, "{}" , ns) ;
300312 } ,
301313
302314 FormatType :: CommonISO => {
303315 let now = SystemTime :: now ( ) ;
304316 if self . utc {
305317 let dt: DateTime < Utc > = now. into ( ) ;
306318 use std:: fmt:: Write ;
307- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}" ,
319+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}" ,
308320 dt. year( ) , dt. month( ) , dt. day( ) ,
309- dt. hour( ) , dt. minute( ) , dt. second( ) ) . unwrap ( ) ;
321+ dt. hour( ) , dt. minute( ) , dt. second( ) ) ;
310322 } else {
311323 let dt: DateTime < Local > = now. into ( ) ;
312324 use std:: fmt:: Write ;
313- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}" ,
325+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}" ,
314326 dt. year( ) , dt. month( ) , dt. day( ) ,
315- dt. hour( ) , dt. minute( ) , dt. second( ) ) . unwrap ( ) ;
327+ dt. hour( ) , dt. minute( ) , dt. second( ) ) ;
316328 }
317329 } ,
318330
@@ -321,17 +333,17 @@ impl TimeFormatter {
321333 if self . utc {
322334 let dt: DateTime < Utc > = now. into ( ) ;
323335 use std:: fmt:: Write ;
324- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}" ,
336+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}" ,
325337 dt. year( ) , dt. month( ) , dt. day( ) ,
326338 dt. hour( ) , dt. minute( ) , dt. second( ) ,
327- dt. timestamp_subsec_millis( ) ) . unwrap ( ) ;
339+ dt. timestamp_subsec_millis( ) ) ;
328340 } else {
329341 let dt: DateTime < Local > = now. into ( ) ;
330342 use std:: fmt:: Write ;
331- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}" ,
343+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}" ,
332344 dt. year( ) , dt. month( ) , dt. day( ) ,
333345 dt. hour( ) , dt. minute( ) , dt. second( ) ,
334- dt. timestamp_subsec_millis( ) ) . unwrap ( ) ;
346+ dt. timestamp_subsec_millis( ) ) ;
335347 }
336348 } ,
337349
@@ -340,17 +352,17 @@ impl TimeFormatter {
340352 if self . utc {
341353 let dt: DateTime < Utc > = now. into ( ) ;
342354 use std:: fmt:: Write ;
343- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}" ,
355+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}" ,
344356 dt. year( ) , dt. month( ) , dt. day( ) ,
345357 dt. hour( ) , dt. minute( ) , dt. second( ) ,
346- dt. timestamp_subsec_micros( ) ) . unwrap ( ) ;
358+ dt. timestamp_subsec_micros( ) ) ;
347359 } else {
348360 let dt: DateTime < Local > = now. into ( ) ;
349361 use std:: fmt:: Write ;
350- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}" ,
362+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:06}" ,
351363 dt. year( ) , dt. month( ) , dt. day( ) ,
352364 dt. hour( ) , dt. minute( ) , dt. second( ) ,
353- dt. timestamp_subsec_micros( ) ) . unwrap ( ) ;
365+ dt. timestamp_subsec_micros( ) ) ;
354366 }
355367 } ,
356368
@@ -359,17 +371,17 @@ impl TimeFormatter {
359371 if self . utc {
360372 let dt: DateTime < Utc > = now. into ( ) ;
361373 use std:: fmt:: Write ;
362- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}" ,
374+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}" ,
363375 dt. year( ) , dt. month( ) , dt. day( ) ,
364376 dt. hour( ) , dt. minute( ) , dt. second( ) ,
365- dt. timestamp_subsec_nanos( ) ) . unwrap ( ) ;
377+ dt. timestamp_subsec_nanos( ) ) ;
366378 } else {
367379 let dt: DateTime < Local > = now. into ( ) ;
368380 use std:: fmt:: Write ;
369- write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}" ,
381+ let _ = write ! ( self . timestamp_buf, "{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}" ,
370382 dt. year( ) , dt. month( ) , dt. day( ) ,
371383 dt. hour( ) , dt. minute( ) , dt. second( ) ,
372- dt. timestamp_subsec_nanos( ) ) . unwrap ( ) ;
384+ dt. timestamp_subsec_nanos( ) ) ;
373385 }
374386 } ,
375387
@@ -378,11 +390,11 @@ impl TimeFormatter {
378390 if self . utc {
379391 let dt: DateTime < Utc > = now. into ( ) ;
380392 use std:: fmt:: Write ;
381- write ! ( self . timestamp_buf, "{}" , dt. format( "%Y-%m-%dT%H:%M:%S%.3f%z" ) ) . unwrap ( ) ;
393+ let _ = write ! ( self . timestamp_buf, "{}" , dt. format( "%Y-%m-%dT%H:%M:%S%.3f%z" ) ) ;
382394 } else {
383395 let dt: DateTime < Local > = now. into ( ) ;
384396 use std:: fmt:: Write ;
385- write ! ( self . timestamp_buf, "{}" , dt. format( "%Y-%m-%dT%H:%M:%S%.3f%z" ) ) . unwrap ( ) ;
397+ let _ = write ! ( self . timestamp_buf, "{}" , dt. format( "%Y-%m-%dT%H:%M:%S%.3f%z" ) ) ;
386398 }
387399 } ,
388400
@@ -411,12 +423,12 @@ impl TimeFormatter {
411423 . with_nanosecond ( subsec_millis * 1_000_000 ) . unwrap ( ) ;
412424
413425 use std:: fmt:: Write ;
414- write ! ( self . timestamp_buf, "{}" , dt. format( fmt) ) . unwrap ( ) ;
426+ let _ = write ! ( self . timestamp_buf, "{}" , dt. format( fmt) ) ;
415427 } else {
416428 let total_ms = duration. as_millis ( ) ;
417429 use std:: fmt:: Write ;
418- write ! ( self . timestamp_buf, "{}.{:03}" ,
419- total_ms / 1000 , total_ms % 1000 ) . unwrap ( ) ;
430+ let _ = write ! ( self . timestamp_buf, "{}.{:03}" ,
431+ total_ms / 1000 , total_ms % 1000 ) ;
420432 }
421433 } else {
422434 // Handle absolute timestamps with custom format
@@ -425,11 +437,11 @@ impl TimeFormatter {
425437 if self . utc {
426438 let dt: DateTime < Utc > = now. into ( ) ;
427439 use std:: fmt:: Write ;
428- write ! ( self . timestamp_buf, "{}" , dt. format( fmt) ) . unwrap ( ) ;
440+ let _ = write ! ( self . timestamp_buf, "{}" , dt. format( fmt) ) ;
429441 } else {
430442 let dt: DateTime < Local > = now. into ( ) ;
431443 use std:: fmt:: Write ;
432- write ! ( self . timestamp_buf, "{}" , dt. format( fmt) ) . unwrap ( ) ;
444+ let _ = write ! ( self . timestamp_buf, "{}" , dt. format( fmt) ) ;
433445 }
434446 }
435447 }
0 commit comments