1 | //! > Polyfill for `is_terminal` stdlib feature for use with older MSRVs |
2 | |
3 | #![cfg_attr (docsrs, feature(doc_auto_cfg))] |
4 | #![warn (clippy::print_stderr)] |
5 | #![warn (clippy::print_stdout)] |
6 | |
7 | /// Trait to determine if a descriptor/handle refers to a terminal/tty. |
8 | pub trait IsTerminal: sealed::Sealed { |
9 | /// Returns `true` if the descriptor/handle refers to a terminal/tty. |
10 | /// |
11 | /// On platforms where Rust does not know how to detect a terminal yet, this will return |
12 | /// `false`. This will also return `false` if an unexpected error occurred, such as from |
13 | /// passing an invalid file descriptor. |
14 | /// |
15 | /// # Platform-specific behavior |
16 | /// |
17 | /// On Windows, in addition to detecting consoles, this currently uses some heuristics to |
18 | /// detect older msys/cygwin/mingw pseudo-terminals based on device name: devices with names |
19 | /// starting with `msys-` or `cygwin-` and ending in `-pty` will be considered terminals. |
20 | /// Note that this [may change in the future][changes]. |
21 | /// |
22 | /// [changes]: std::io#platform-specific-behavior |
23 | fn is_terminal(&self) -> bool; |
24 | } |
25 | |
26 | mod sealed { |
27 | pub trait Sealed {} |
28 | } |
29 | |
30 | macro_rules! impl_is_terminal { |
31 | ($($t:ty),*$(,)?) => {$( |
32 | impl sealed::Sealed for $t {} |
33 | |
34 | impl IsTerminal for $t { |
35 | #[inline] |
36 | fn is_terminal(&self) -> bool { |
37 | std::io::IsTerminal::is_terminal(self) |
38 | } |
39 | } |
40 | )*} |
41 | } |
42 | |
43 | impl_is_terminal!( |
44 | std::fs::File, |
45 | std::io::Stdin, |
46 | std::io::StdinLock<'_>, |
47 | std::io::Stdout, |
48 | std::io::StdoutLock<'_>, |
49 | std::io::Stderr, |
50 | std::io::StderrLock<'_> |
51 | ); |
52 | |