1use atty::{self, Stream};
12use libc::{self, signal};
13use std::{fmt::Display, time::SystemTime};
14
15pub fn current_executable() -> String {
17 std::env::current_exe()
18 .ok()
19 .and_then(|abspath| {
20 abspath
21 .file_name()
22 .map(|f| f.to_str().unwrap_or("").to_string())
23 })
24 .unwrap_or("".to_string())
25}
26
27pub fn panic_on_error<T>(result: std::io::Result<T>) -> T {
29 result.unwrap_or_else(|error| die!("{}: {}", current_executable(), error))
30}
31
32pub fn print_solution(verdict: &str) {
34 puts!("s {}\n", verdict);
35}
36
37pub fn print_key_value(key: &str, value: impl Display) {
39 requires!(key.len() < 35);
40 comment!("{:<35} {:>15}", format!("{}:", key), value);
41}
42
43pub fn install_signal_handler() {
45 assert!(unsafe { signal(libc::SIGPIPE, libc::SIG_DFL) } != libc::SIG_ERR);
47}
48
49pub fn unreachable() -> ! {
51 invariant!(false, "unreachable");
52 unsafe { std::hint::unreachable_unchecked() }
53}
54
55pub fn is_a_tty() -> bool {
57 atty::is(Stream::Stdout)
58}
59
60pub struct Timer {
62 name: &'static str,
64 start: SystemTime,
66 pub disabled: bool,
68}
69
70impl Timer {
71 pub fn name(name: &'static str) -> Timer {
73 Timer {
74 name,
75 start: SystemTime::now(),
76 disabled: false,
77 }
78 }
79}
80
81impl Drop for Timer {
82 fn drop(&mut self) {
84 if self.disabled {
85 return;
86 }
87 let elapsed_time = self.start.elapsed().expect("failed to get time");
88 print_key_value(
89 &format!("{} (s)", self.name),
90 format!(
91 "{}.{:03}",
92 elapsed_time.as_secs(),
93 elapsed_time.subsec_millis()
94 ),
95 );
96 }
97}