1use std::io::{self, IsTerminal, Write};
4use std::process::{Command, Stdio};
5
6use taba_client::{Client, Config, Error as ApiError};
7
8use crate::app::Platform;
9use crate::profile::Os;
10use crate::tui::{term::RawTerminal, Terminal};
11
12pub struct RealPlatform;
13
14impl Platform for RealPlatform {
15 fn env(&self, name: &str) -> Option<String> {
16 std::env::var(name).ok()
17 }
18
19 fn os(&self) -> Os {
20 Os::current()
21 }
22
23 fn stdin_is_tty(&self) -> bool {
24 io::stdin().is_terminal()
25 }
26
27 fn stdout_is_tty(&self) -> bool {
28 io::stdout().is_terminal()
29 }
30
31 fn client(&self, config: Config) -> Result<Client, ApiError> {
32 Client::new(config)
33 }
34
35 fn exec(&self, command: &str, stdin: &[u8]) -> io::Result<i32> {
36 let mut shell = if cfg!(windows) {
37 let mut c = Command::new("cmd");
38 c.args(["/C", command]);
39 c
40 } else {
41 let mut c = Command::new("sh");
42 c.args(["-c", command]);
43 c
44 };
45 let mut child = shell.stdin(Stdio::piped()).spawn()?;
46 if let Some(mut pipe) = child.stdin.take() {
47 let _ = pipe.write_all(stdin);
49 }
50 Ok(child.wait()?.code().unwrap_or(-1))
51 }
52
53 fn terminal(&self) -> Option<Box<dyn Terminal>> {
54 RawTerminal::open()
55 .ok()
56 .map(|t| Box::new(t) as Box<dyn Terminal>)
57 }
58}