use std::io::{self, Write};
use super::escape_filter::EscapeSequenceFilter;
pub(super) fn deliver_filtered_output(
filter: &mut EscapeSequenceFilter,
writer: &mut impl Write,
input: &[u8],
commit: impl FnOnce(&[u8]),
) -> io::Result<()> {
let output = filter.filter(input);
if output.is_empty() {
return Ok(());
}
writer.write_all(&output)?;
commit(&output);
let _ = writer.flush();
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::pty::terminal_screen::ScreenModeTracker;
struct FailedWriter;
impl Write for FailedWriter {
fn write(&mut self, _buffer: &[u8]) -> io::Result<usize> {
Err(io::Error::other("injected delivery failure"))
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
#[test]
fn failed_delivery_does_not_commit_screen_transition() {
let mut filter = EscapeSequenceFilter::new();
let mut tracker = ScreenModeTracker::new();
let mut committed = false;
let result =
deliver_filtered_output(&mut filter, &mut FailedWriter, b"\x1b[?1049h", |output| {
committed = true;
tracker.observe(output);
});
assert!(result.is_err());
assert!(!committed);
}
#[test]
fn filtered_payload_does_not_commit_screen_transition() {
let mut filter = EscapeSequenceFilter::new();
let mut tracker = ScreenModeTracker::new();
let mut output = Vec::new();
let mut committed = false;
deliver_filtered_output(
&mut filter,
&mut output,
b"\x1b]10;payload\x1b[?1049h\x07",
|delivered| {
committed = true;
tracker.observe(delivered);
},
)
.unwrap();
assert!(output.is_empty());
assert!(!committed);
}
#[test]
fn successful_delivery_commits_screen_transition() {
let mut filter = EscapeSequenceFilter::new();
let mut tracker = ScreenModeTracker::new();
let mut output = Vec::new();
let mut observed = None;
deliver_filtered_output(&mut filter, &mut output, b"\x1b[?1049h", |delivered| {
observed = tracker.observe(delivered);
})
.unwrap();
assert_eq!(output, b"\x1b[?1049h");
assert_eq!(observed, Some(true));
}
}