Skip to main content

artifactize_core/platform/
console.rs

1//! Keep help visible when a desktop launch creates a console just for this process.
2
3use std::io::{self, IsTerminal, Write};
4
5/// Arguments and redirected input never turn a command into an interactive prompt.
6fn should_pause(owns_console: bool, has_args: bool, stdin_is_console: bool) -> bool {
7    owns_console && !has_args && stdin_is_console
8}
9
10#[cfg(windows)]
11fn owns_console() -> bool {
12    use windows_sys::Win32::System::Console::GetConsoleProcessList;
13
14    let mut process = 0;
15    // SAFETY: process points to one writable DWORD; the supplied buffer length is one.
16    // The API returns the total attached process count even if the buffer is too small.
17    unsafe { GetConsoleProcessList(&mut process, 1) == 1 }
18}
19
20#[cfg(unix)]
21fn owns_console() -> bool {
22    false
23}
24
25/// Only a no-argument desktop launch with console input AND output may wait for Enter.
26pub fn pause_after_help(has_args: bool) -> io::Result<()> {
27    if !has_args
28        && io::stdout().is_terminal()
29        && should_pause(owns_console(), has_args, io::stdin().is_terminal())
30    {
31        let mut output = io::stdout().lock();
32        writeln!(
33            output,
34            "\nOpen Windows Terminal or PowerShell and run artifactize there. Press Enter to exit."
35        )?;
36        output.flush()?;
37        drop(output);
38        io::stdin().read_line(&mut String::new())?;
39    }
40    Ok(())
41}
42
43#[cfg(test)]
44mod tests {
45    use super::should_pause;
46
47    #[test]
48    fn only_owned_console_help_with_console_input_pauses() {
49        for (owns_console, has_args, stdin_is_console, expected) in [
50            (false, false, false, false),
51            (false, false, true, false),
52            (false, true, false, false),
53            (false, true, true, false),
54            (true, false, false, false),
55            (true, false, true, true),
56            (true, true, false, false),
57            (true, true, true, false),
58        ] {
59            assert_eq!(
60                should_pause(owns_console, has_args, stdin_is_console),
61                expected,
62                "owns_console={owns_console}, has_args={has_args}, stdin_is_console={stdin_is_console}"
63            );
64        }
65    }
66}