cursive-image 0.0.6

Image view for the Cursive TUI library
Documentation
use {
    base64::{engine::general_purpose::*, write::*},
    std::io::{self, BufRead, Write},
};

const COMMAND_START: &str = "\x1b_G";
const COMMAND_END: &str = "\x1b\\";
const COMMAND_END_FIRST: u8 = b'\x1b';
const COMMAND_END_REST: &str = "\\";

//
// KittyWriter
//

/// Kitty writer utilities.
pub trait KittyWriter: Sized {
    // Write start of Kitty graphics protocol command.
    fn write_start(&mut self) -> io::Result<()>;

    // Write end of Kitty graphics protocol command.
    fn write_end(&mut self) -> io::Result<()>;

    // Write as Base64.
    fn write_base64(self, data: &[u8]) -> io::Result<Self>;
}

impl<WriteT> KittyWriter for WriteT
where
    WriteT: io::Write,
{
    fn write_start(&mut self) -> io::Result<()> {
        // self.flush()?;
        write!(self, "{}", COMMAND_START)
    }

    fn write_end(&mut self) -> io::Result<()> {
        write!(self, "{}", COMMAND_END)?;
        self.flush()
    }

    fn write_base64(self, data: &[u8]) -> io::Result<Self> {
        // Note: *must* be padded
        let mut encoder = EncoderWriter::new(self, &STANDARD);
        encoder.write_all(data)?;
        encoder.finish()
    }
}

//
// KittyReader
//

/// Kitty reader utilities.
#[allow(unused)]
pub trait KittyReader {
    /// Read Kitty response to command.
    fn read_response(&mut self) -> io::Result<Option<Vec<u8>>>;
}

impl<ReadT> KittyReader for ReadT
where
    ReadT: io::Read,
{
    fn read_response(&mut self) -> io::Result<Option<Vec<u8>>> {
        // TODO: this can't be it...

        let mut buffer = vec![0; COMMAND_START.len()];
        self.read_exact(&mut buffer)?;
        if buffer == COMMAND_START.as_bytes() {
            // Keep reading until end
            let mut response = Vec::default();

            let mut reader = io::BufReader::new(self);
            reader.read_until(COMMAND_END_FIRST, &mut response)?;
            let reader = reader.into_inner();

            let mut buffer = vec![0; COMMAND_END_REST.len()];
            reader.read_exact(&mut buffer)?;
            if buffer == COMMAND_END_REST.as_bytes() {
                response.pop(); // COMMAND_END_FIRST
                return Ok(Some(response));
            }
        }

        Ok(None)
    }
}