use CatCode::*;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum CatCode {
Escape = 0,
BeginGroup = 1,
EndGroup = 2,
MathShift = 3,
AlignmentTab = 4,
EndOfLine = 5,
Parameter = 6,
Superscript = 7,
Subscript = 8,
Ignored = 9,
Space = 10,
Letter = 11,
#[default]
Other = 12,
Active = 13,
Comment = 14,
Invalid = 15,
}
impl TryFrom<u8> for CatCode {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Escape),
1 => Ok(BeginGroup),
2 => Ok(EndGroup),
3 => Ok(MathShift),
4 => Ok(AlignmentTab),
5 => Ok(EndOfLine),
6 => Ok(Parameter),
7 => Ok(Superscript),
8 => Ok(Subscript),
9 => Ok(Ignored),
10 => Ok(Space),
11 => Ok(Letter),
12 => Ok(Other),
13 => Ok(Active),
14 => Ok(Comment),
15 => Ok(Invalid),
_ => Err(()),
}
}
}
impl std::fmt::Display for CatCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} ({})",
*self as u8,
match self {
Escape => "escape",
BeginGroup => "begin group",
EndGroup => "end group",
MathShift => "math shift",
AlignmentTab => "alignment tab",
EndOfLine => "end of line",
Parameter => "parameter",
Superscript => "superscript",
Subscript => "subscript",
Ignored => "ignored",
Space => "space",
Letter => "letter",
Other => "other",
Active => "active",
Comment => "comment",
Invalid => "invalid",
}
)?;
Ok(())
}
}
impl CatCode {
pub const INITEX_DEFAULTS: [CatCode; 128] = [
Ignored, Other, Other, Other, Other, Other, Other, Other, Other, Other,
EndOfLine, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, Other, Other, Other, Space, Other, Other, Other, Other, Comment, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other, Other,
Other, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Other, Escape, Other, Other, Other, Other, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Other, Other, Other, Other, Invalid, ];
pub const PLAIN_TEX_DEFAULTS: [CatCode; 128] = [
Ignored, Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Space, EndOfLine, Other,
Active, Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Space, Other,
Other,
Parameter, MathShift, Comment, AlignmentTab, Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Other,
Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Other,
Escape, Other,
Superscript, Subscript, Other,
Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, BeginGroup, Other,
EndGroup, Active, Invalid, ];
}
#[cfg(test)]
mod tests {
use crate::token::catcode::CatCode;
#[test]
fn serialize_and_deserialize_cat_code() {
let all_raw_cat_codes = vec![
CatCode::BeginGroup,
CatCode::EndGroup,
CatCode::MathShift,
CatCode::AlignmentTab,
CatCode::Parameter,
CatCode::Superscript,
CatCode::Subscript,
CatCode::Space,
CatCode::Letter,
CatCode::Other,
CatCode::Active,
CatCode::Escape,
CatCode::EndOfLine,
CatCode::Ignored,
CatCode::Comment,
CatCode::Invalid,
];
for cat_code in all_raw_cat_codes {
let u: u8 = cat_code as u8;
let recovered: CatCode = u.try_into().unwrap();
assert_eq!(recovered, cat_code);
}
}
}