use std::sync::Arc;
pub(crate) const MAX_TERMINAL_PASSTHROUGH_PAYLOAD_BYTES: usize = 8 * 1024 * 1024;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TerminalPassthrough {
kind: TerminalPassthroughKind,
cursor_x: u32,
cursor_y: u32,
payload: Arc<[u8]>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TerminalPassthroughKind {
KittyGraphics,
Sixel,
}
impl TerminalPassthrough {
#[must_use]
pub fn kitty_graphics(cursor_x: u32, cursor_y: u32, payload: impl Into<Vec<u8>>) -> Self {
Self {
kind: TerminalPassthroughKind::KittyGraphics,
cursor_x,
cursor_y,
payload: Arc::from(payload.into()),
}
}
#[must_use]
pub fn sixel(cursor_x: u32, cursor_y: u32, payload: impl Into<Vec<u8>>) -> Self {
Self {
kind: TerminalPassthroughKind::Sixel,
cursor_x,
cursor_y,
payload: Arc::from(payload.into()),
}
}
#[must_use]
pub const fn kind(&self) -> TerminalPassthroughKind {
self.kind
}
#[must_use]
pub const fn cursor_x(&self) -> u32 {
self.cursor_x
}
#[must_use]
pub const fn cursor_y(&self) -> u32 {
self.cursor_y
}
#[must_use]
pub fn payload(&self) -> &[u8] {
&self.payload
}
#[must_use]
pub fn render_sequence(&self) -> Vec<u8> {
match self.kind {
TerminalPassthroughKind::KittyGraphics => {
let mut sequence = Vec::with_capacity(self.payload.len() + 4);
sequence.extend_from_slice(b"\x1b_");
sequence.extend_from_slice(&self.payload);
sequence.extend_from_slice(b"\x1b\\");
sequence
}
TerminalPassthroughKind::Sixel => {
let mut sequence = Vec::with_capacity(self.payload.len() + 4);
sequence.extend_from_slice(b"\x1bP");
sequence.extend_from_slice(&self.payload);
sequence.extend_from_slice(b"\x1b\\");
sequence
}
}
}
}
#[cfg(test)]
mod tests {
use super::TerminalPassthrough;
#[test]
fn renders_kitty_apc_sequence() {
let passthrough = TerminalPassthrough::kitty_graphics(0, 0, b"Gf=100;AAAA".to_vec());
assert_eq!(passthrough.render_sequence(), b"\x1b_Gf=100;AAAA\x1b\\");
}
#[test]
fn renders_sixel_dcs_sequence() {
let passthrough = TerminalPassthrough::sixel(0, 0, b"q#0!10~".to_vec());
assert_eq!(passthrough.render_sequence(), b"\x1bPq#0!10~\x1b\\");
}
}