use crate::printer::ReadKey;
use crate::ViuResult;
use console::{Key, Term};
use std::io::Write;
use std::sync::LazyLock;
static SIXEL_SUPPORT: LazyLock<bool> = LazyLock::new(check_sixel_support);
pub fn is_sixel_supported() -> bool {
*SIXEL_SUPPORT
}
fn check_device_attrs(stdin: &impl ReadKey, stdout: &mut impl Write) -> ViuResult<bool> {
write!(stdout, "\x1b[c")?;
stdout.flush()?;
let mut response = String::new();
while let Ok(key) = stdin.read_key() {
if key == Key::Unknown {
break;
}
if let Key::Char(c) = key {
response.push(c);
if c == 'c' {
break;
}
}
}
Ok(response.contains(";4;") || response.contains(";4c"))
}
fn check_sixel_support() -> bool {
let mut stdout = std::io::stdout();
let stdin = Term::stdout();
check_device_attrs(&stdin, &mut stdout).unwrap_or(false)
}
#[cfg(test)]
mod tests {
use console::Key;
use crate::printer::{sixel_util::check_device_attrs, TestKeys};
#[test]
fn should_detect_device_attrs() {
let mut stdout = Vec::new();
let test_stdin_data = [
Key::UnknownEscSeq(['[', '?', '6'].into()),
Key::Char('2'),
Key::Char(';'),
Key::Char('1'),
Key::Char(';'),
Key::Char('4'),
Key::Char('c'),
];
let test_stdin = TestKeys::new(&test_stdin_data);
check_device_attrs(&test_stdin, &mut stdout).unwrap();
let result = std::str::from_utf8(&stdout).unwrap();
assert_eq!(result, "\x1b[c");
assert!(test_stdin.reached_end());
}
}