use super::TerminalOutput;
use std::io::{self, Write};
use std::sync::Arc;
#[cfg(windows)]
use kernel::windows_kernel::ansi_support::{try_enable_ansi_support, windows_supportable};
#[cfg(windows)]
use kernel::windows_kernel::exit;
#[cfg(windows)]
use kernel::windows_kernel::ScreenBuffer;
#[cfg(windows)]
use kernel::windows_kernel::Cursor;
#[cfg(unix)]
use kernel::unix_kernel::terminal::{exit, pos, terminal_size};
#[cfg(unix)]
pub fn get_terminal_size() -> (u16, u16) {
terminal_size()
}
#[cfg(windows)]
pub fn get_terminal_size() -> (u16, u16) {
if let Ok(buffer) = ScreenBuffer::current() {
let size = buffer.info().unwrap().terminal_size();
(size.width as u16, size.height as u16)
} else {
(0, 0)
}
}
#[cfg(unix)]
pub fn get_cursor_position() -> (u16, u16) {
if let Ok(pos) = pos() {
pos
} else {
(0, 0)
}
}
#[cfg(windows)]
pub fn get_cursor_position() -> (u16, u16) {
if let Ok(cursor) = Cursor::new() {
cursor.position().unwrap().into()
} else {
(0, 0)
}
}
pub fn exit_terminal() {
exit();
}
#[cfg(windows)]
pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> {
let mut term: Option<T> = None;
let mut does_support = true;
if !windows_supportable() {
does_support = try_enable_ansi_support();
if !does_support {
term = Some(winapi_impl);
}
}
if does_support {
term = Some(unix_impl);
}
term
}
pub fn write(stdout: &Option<&Arc<TerminalOutput>>, string: String) -> io::Result<usize> {
match stdout {
None => {
print!("{}", string.as_str());
match io::stdout().flush() {
Ok(_) => Ok(string.len()),
Err(e) => Err(e),
}
}
Some(output) => output.write_string(string),
}
}
pub fn write_str(stdout: &Option<&Arc<TerminalOutput>>, string: &str) -> io::Result<usize> {
match stdout {
None => match io::stdout().flush() {
Ok(_) => {
write!(io::stdout(), "{}", string)?;
Ok(string.len())
}
Err(e) => Err(e),
},
Some(output) => output.write_str(string),
}
}