| 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 | |