#![cfg(any(feature = "bash", feature = "fish"))]
#[derive(PartialEq)]
pub(crate) enum Char {
Bell,
Backspace,
Escape,
FormFeed,
NewLine,
CarriageReturn,
HorizontalTab,
VerticalTab,
Control(u8),
Backslash,
SingleQuote,
DoubleQuote,
Delete,
PrintableInert(u8),
Printable(u8),
Utf8(char),
}
impl Char {
pub fn from(ch: char) -> Self {
let ascii: Result<u8, _> = ch.try_into();
use Char::*;
match ascii {
Ok(ascii) => match ascii {
BEL => Bell,
BS => Backspace,
ESC => Escape,
FF => FormFeed,
LF => NewLine,
CR => CarriageReturn,
TAB => HorizontalTab,
VT => VerticalTab,
0x00..=0x06 | 0x0E..=0x1A | 0x1C..=0x1F => Control(ascii),
b'\\' => Backslash,
b'\'' => SingleQuote,
b'\"' => DoubleQuote,
DEL => Delete,
b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' => PrintableInert(ascii),
b',' | b'.' | b'/' | b'_' | b'-' => PrintableInert(ascii),
b'|' | b'&' | b';' | b'(' | b')' | b'<' | b'>' => Printable(ascii),
b' ' | b'?' | b'[' | b']' | b'{' | b'}' | b'`' => Printable(ascii),
b'~' | b'!' | b'$' | b'@' | b'+' | b'=' | b'*' => Printable(ascii),
b'%' | b'#' | b':' | b'^' => Printable(ascii),
0x80..=0xff => Utf8(ch),
},
Err(_) => Utf8(ch),
}
}
#[inline]
pub fn is_inert(&self) -> bool {
matches!(self, Char::PrintableInert(_))
}
}
const BEL: u8 = 0x07; const BS: u8 = 0x08; const TAB: u8 = 0x09; const LF: u8 = 0x0A; const VT: u8 = 0x0B; const FF: u8 = 0x0C; const CR: u8 = 0x0D; const ESC: u8 = 0x1B; const DEL: u8 = 0x7F;