use crate::SyntaxKind;
#[expect(
clippy::too_many_lines,
reason = "flat lookup table, splitting hurts readability"
)]
pub fn lex_punctuation(bytes: &[u8], pos: usize) -> Option<(SyntaxKind, usize)> {
use SyntaxKind::{
AMP, AMP_AMP, AT, AT_L_BRACKET, BACKSLASH, BANG, BANG_EQ, CARET, COLON, COLON_COLON, COMMA,
DIVERT, DOT, EQ, EQ_EQ, FAT_ARROW, GLUE, GT, GT_EQ, HASH, L_BRACE, L_BRACKET, L_PAREN, LT,
LT_EQ, MINUS, MINUS_EQ, PERCENT, PIPE, PLUS, PLUS_EQ, QUESTION, QUOTE, R_BRACE, R_BRACKET,
R_PAREN, SEMICOLON, SLASH, SLASH_EQ, STAR, STAR_EQ, THREAD, TILDE,
};
let b = bytes[pos];
let len = bytes.len();
let b1 = if pos + 1 < len {
Some(bytes[pos + 1])
} else {
None
};
Some(match b {
b'@' => {
if b1 == Some(b'[') {
(AT_L_BRACKET, 2)
} else {
(AT, 1)
}
}
b'-' => {
if b1 == Some(b'>') {
(DIVERT, 2)
} else if b1 == Some(b'=') {
(MINUS_EQ, 2)
} else {
(MINUS, 1)
}
}
b'<' => {
if b1 == Some(b'>') {
(GLUE, 2)
} else if b1 == Some(b'-') {
(THREAD, 2)
} else if b1 == Some(b'=') {
(LT_EQ, 2)
} else {
(LT, 1)
}
}
b'=' => {
if b1 == Some(b'=') {
(EQ_EQ, 2)
} else if b1 == Some(b'>') {
(FAT_ARROW, 2)
} else {
(EQ, 1)
}
}
b'!' => {
if b1 == Some(b'=') {
(BANG_EQ, 2)
} else {
(BANG, 1)
}
}
b':' => {
if b1 == Some(b':') {
(COLON_COLON, 2)
} else {
(COLON, 1)
}
}
b'|' => (PIPE, 1),
b'&' => {
if b1 == Some(b'&') {
(AMP_AMP, 2)
} else {
(AMP, 1)
}
}
b'+' => {
if b1 == Some(b'=') {
(PLUS_EQ, 2)
} else {
(PLUS, 1)
}
}
b'>' => {
if b1 == Some(b'=') {
(GT_EQ, 2)
} else {
(GT, 1)
}
}
b'*' => {
if b1 == Some(b'=') {
(STAR_EQ, 2)
} else {
(STAR, 1)
}
}
b'/' => {
if b1 == Some(b'=') {
(SLASH_EQ, 2)
} else {
(SLASH, 1)
}
}
b'%' => (PERCENT, 1),
b'^' => (CARET, 1),
b'?' => (QUESTION, 1),
b'(' => (L_PAREN, 1),
b')' => (R_PAREN, 1),
b'{' => (L_BRACE, 1),
b'}' => (R_BRACE, 1),
b'[' => (L_BRACKET, 1),
b']' => (R_BRACKET, 1),
b',' => (COMMA, 1),
b'.' => (DOT, 1),
b'#' => (HASH, 1),
b';' => (SEMICOLON, 1),
b'~' => (TILDE, 1),
b'\\' => (BACKSLASH, 1),
b'"' => (QUOTE, 1),
_ => return None,
})
}