use russh::Pty;
pub fn configure_terminal_modes() -> Vec<(Pty, u32)> {
vec![
(Pty::VINTR, 0x03), (Pty::VQUIT, 0x1C), (Pty::VERASE, 0x7F), (Pty::VKILL, 0x15), (Pty::VEOF, 0x04), (Pty::VEOL, 0xFF), (Pty::VEOL2, 0xFF), (Pty::VSTART, 0x11), (Pty::VSTOP, 0x13), (Pty::VSUSP, 0x1A), (Pty::VREPRINT, 0x12), (Pty::VWERASE, 0x17), (Pty::VLNEXT, 0x16), (Pty::VDISCARD, 0x0F), (Pty::IGNPAR, 0), (Pty::PARMRK, 0), (Pty::INPCK, 0), (Pty::ISTRIP, 0), (Pty::INLCR, 0), (Pty::IGNCR, 0), (Pty::ICRNL, 1), (Pty::IXON, 0), (Pty::IXANY, 0), (Pty::IXOFF, 0), (Pty::IMAXBEL, 1), (Pty::ISIG, 1), (Pty::ICANON, 1), (Pty::ECHO, 1), (Pty::ECHOE, 1), (Pty::ECHOK, 1), (Pty::ECHONL, 0), (Pty::NOFLSH, 0), (Pty::TOSTOP, 0), (Pty::IEXTEN, 1), (Pty::ECHOCTL, 1), (Pty::ECHOKE, 1), (Pty::PENDIN, 0), (Pty::OPOST, 1), (Pty::ONLCR, 1), (Pty::OCRNL, 0), (Pty::ONOCR, 0), (Pty::ONLRET, 0), (Pty::CS8, 1), (Pty::PARENB, 0), (Pty::PARODD, 0), (Pty::TTY_OP_ISPEED, 38400), (Pty::TTY_OP_OSPEED, 38400), ]
}
#[cfg(test)]
mod tests {
use super::*;
fn find_mode(modes: &[(Pty, u32)], target: Pty) -> Option<u32> {
modes.iter().find(|(k, _)| *k == target).map(|(_, v)| *v)
}
#[test]
fn test_configure_terminal_modes_returns_non_empty() {
let modes = configure_terminal_modes();
assert!(!modes.is_empty(), "Terminal modes should not be empty");
}
#[test]
fn test_configure_terminal_modes_count() {
let modes = configure_terminal_modes();
assert!(
modes.len() >= 30,
"Expected at least 30 terminal modes, got {}",
modes.len()
);
}
#[test]
fn test_control_characters_configured() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::VINTR),
Some(0x03),
"VINTR should be Ctrl+C (0x03)"
);
assert_eq!(
find_mode(&modes, Pty::VEOF),
Some(0x04),
"VEOF should be Ctrl+D (0x04)"
);
assert_eq!(
find_mode(&modes, Pty::VSUSP),
Some(0x1A),
"VSUSP should be Ctrl+Z (0x1A)"
);
assert_eq!(
find_mode(&modes, Pty::VERASE),
Some(0x7F),
"VERASE should be DEL (0x7F)"
);
assert_eq!(
find_mode(&modes, Pty::VKILL),
Some(0x15),
"VKILL should be Ctrl+U (0x15)"
);
}
#[test]
fn test_signal_generation_enabled() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::ISIG),
Some(1),
"ISIG should be enabled for signal generation"
);
}
#[test]
fn test_canonical_mode_enabled() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::ICANON),
Some(1),
"ICANON should be enabled for line editing"
);
}
#[test]
fn test_echo_enabled() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::ECHO),
Some(1),
"ECHO should be enabled by default"
);
}
#[test]
fn test_cr_to_nl_mapping() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::ICRNL),
Some(1),
"ICRNL should be enabled for Enter key"
);
}
#[test]
fn test_output_processing() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::OPOST),
Some(1),
"OPOST should be enabled for output processing"
);
assert_eq!(
find_mode(&modes, Pty::ONLCR),
Some(1),
"ONLCR should be enabled for proper line endings"
);
}
#[test]
fn test_8bit_character_size() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::CS8),
Some(1),
"CS8 should be enabled for 8-bit characters"
);
}
#[test]
fn test_flow_control_disabled() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::IXON),
Some(0),
"IXON should be disabled (no flow control)"
);
assert_eq!(
find_mode(&modes, Pty::IXOFF),
Some(0),
"IXOFF should be disabled (no flow control)"
);
}
#[test]
fn test_baud_rates() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::TTY_OP_ISPEED),
Some(38400),
"Input baud rate should be 38400"
);
assert_eq!(
find_mode(&modes, Pty::TTY_OP_OSPEED),
Some(38400),
"Output baud rate should be 38400"
);
}
#[test]
fn test_parity_disabled() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::PARENB),
Some(0),
"Parity should be disabled"
);
}
#[test]
fn test_disabled_control_chars_set_to_0xff() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::VEOL),
Some(0xFF),
"VEOL should be disabled (0xFF)"
);
assert_eq!(
find_mode(&modes, Pty::VEOL2),
Some(0xFF),
"VEOL2 should be disabled (0xFF)"
);
}
#[test]
fn test_extended_input_processing() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::IEXTEN),
Some(1),
"IEXTEN should be enabled for extended input"
);
}
#[test]
fn test_no_duplicate_modes() {
let modes = configure_terminal_modes();
for (i, (mode_i, _)) in modes.iter().enumerate() {
for (j, (mode_j, _)) in modes.iter().enumerate() {
if i != j {
assert!(
mode_i != mode_j,
"Duplicate terminal mode found: {:?}",
mode_i
);
}
}
}
}
#[test]
fn test_all_control_chars_present() {
let modes = configure_terminal_modes();
let control_chars = [
Pty::VINTR,
Pty::VQUIT,
Pty::VERASE,
Pty::VKILL,
Pty::VEOF,
Pty::VEOL,
Pty::VEOL2,
Pty::VSTART,
Pty::VSTOP,
Pty::VSUSP,
Pty::VREPRINT,
Pty::VWERASE,
Pty::VLNEXT,
Pty::VDISCARD,
];
for ctrl in control_chars {
assert!(
find_mode(&modes, ctrl).is_some(),
"Control character {:?} should be present",
ctrl
);
}
}
#[test]
fn test_xon_xoff_chars() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::VSTART),
Some(0x11),
"VSTART should be Ctrl+Q (0x11)"
);
assert_eq!(
find_mode(&modes, Pty::VSTOP),
Some(0x13),
"VSTOP should be Ctrl+S (0x13)"
);
}
#[test]
fn test_visual_erase_enabled() {
let modes = configure_terminal_modes();
assert_eq!(
find_mode(&modes, Pty::ECHOE),
Some(1),
"ECHOE should be enabled for visual erase"
);
}
}