Skip to main content

ssh_cli/platform/
mod.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Operating-system conditional abstractions.
3//!
4//! Platform initialization ([`initialize_platform`]) is the FIRST operation
5//! executada no `main()`. Ela configura:
6//!
7//! - **Windows**: codepage UTF-8 (65001) via `SetConsoleOutputCP` e `SetConsoleCP`
8//! - **Linux**: sandbox detection (Flatpak/Snap) and XDG paths
9//! - **macOS**: config path resolution under `~/Library/Application Support`
10
11use anyhow::Result;
12
13#[cfg(target_os = "linux")]
14mod linux;
15#[cfg(target_os = "macos")]
16mod macos;
17#[cfg(target_os = "windows")]
18mod windows;
19
20/// Initializes the platform before any I/O.
21///
22/// MUST be called as the first operation in `main()`.
23pub fn initialize_platform() -> Result<()> {
24    #[cfg(target_os = "windows")]
25    {
26        windows::configure_utf8_codepage()?;
27    }
28
29    #[cfg(target_os = "linux")]
30    {
31        linux::detectar_sandbox();
32    }
33
34    #[cfg(target_os = "macos")]
35    {
36        macos::initialize();
37    }
38
39    Ok(())
40}
41
42/// Normalizes a stdin line by stripping trailing `\r` (CRLF → LF).
43///
44/// Required on Windows where pipes may emit `\r\n`.
45#[must_use]
46pub fn normalize_stdin_line(line: &str) -> &str {
47    // Strip any trailing CR/LF combination.
48    line.trim_end_matches(['\r', '\n'])
49}
50
51/// Returns `true` if stdout is connected to a terminal (TTY).
52#[must_use]
53pub fn e_tty() -> bool {
54    std::io::IsTerminal::is_terminal(&std::io::stdout())
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    #[test]
62    fn normalize_strips_trailing_cr() {
63        assert_eq!(normalize_stdin_line("teste\r"), "teste");
64        assert_eq!(normalize_stdin_line("teste\r\n"), "teste");
65        assert_eq!(normalize_stdin_line("teste\n"), "teste");
66        assert_eq!(normalize_stdin_line("teste"), "teste");
67    }
68
69    #[test]
70    fn normalize_empty_string() {
71        assert_eq!(normalize_stdin_line(""), "");
72    }
73
74    #[test]
75    fn normalize_newlines_only() {
76        assert_eq!(normalize_stdin_line("\n\n\n"), "");
77    }
78
79    #[test]
80    fn normalize_mixed_crlf_lf() {
81        assert_eq!(
82            normalize_stdin_line("linha1\r\nlinha2\r\nlinha3"),
83            "linha1\r\nlinha2\r\nlinha3"
84        );
85    }
86
87    #[test]
88    fn normalize_with_spaces() {
89        assert_eq!(
90            normalize_stdin_line("texto com espacos  \r\n"),
91            "texto com espacos  "
92        );
93    }
94
95    #[test]
96    fn is_tty_returns_bool() {
97        let _ = e_tty();
98    }
99}