ass_core/tokenizer/state/context.rs
1//! Tokenization context tracking for state-aware ASS tokenization.
2//!
3//! Defines [`TokenContext`], which records the current lexical context so the
4//! tokenizer can apply context-sensitive rules for ASS script elements that
5//! have different lexical rules in different contexts.
6
7/// Tokenization context for state-aware parsing
8///
9/// Tracks current parsing context to enable context-sensitive tokenization
10/// of ASS script elements that have different lexical rules in different
11/// contexts.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13pub enum TokenContext {
14 /// Top-level document parsing
15 ///
16 /// Default state for processing section headers, comments, and
17 /// top-level document structure.
18 #[default]
19 Document,
20
21 /// Inside section header like `[Events]`
22 ///
23 /// Special tokenization rules for section names within square brackets.
24 SectionHeader,
25
26 /// Inside field definition line
27 ///
28 /// Field values have different whitespace and delimiter handling than
29 /// other contexts.
30 FieldValue,
31
32 /// Inside style override block like {\b1}
33 ///
34 /// Override tags use backslash prefixes and have special syntax rules.
35 StyleOverride,
36
37 /// Inside drawing commands (\p1)
38 ///
39 /// Drawing commands use vector graphics syntax with different
40 /// coordinate and command parsing rules.
41 DrawingCommands,
42
43 /// Inside UU-encoded data (fonts/graphics)
44 ///
45 /// Binary data sections use different character validation and
46 /// line parsing rules.
47 UuEncodedData,
48}
49
50impl TokenContext {
51 /// Check if context allows whitespace skipping
52 #[must_use]
53 pub const fn allows_whitespace_skipping(self) -> bool {
54 !matches!(self, Self::FieldValue | Self::UuEncodedData)
55 }
56
57 /// Check if context is inside a delimited block
58 #[must_use]
59 pub const fn is_delimited_block(self) -> bool {
60 matches!(self, Self::SectionHeader | Self::StyleOverride)
61 }
62
63 /// Get expected closing delimiter for context
64 #[must_use]
65 pub const fn closing_delimiter(self) -> Option<char> {
66 match self {
67 Self::SectionHeader => Some(']'),
68 Self::StyleOverride => Some('}'),
69 _ => None,
70 }
71 }
72
73 /// Transition to field value context after colon
74 #[must_use]
75 pub const fn enter_field_value(self) -> Self {
76 match self {
77 Self::Document => Self::FieldValue,
78 other => other,
79 }
80 }
81
82 /// Reset to document context (typically after newline)
83 #[must_use]
84 pub const fn reset_to_document(self) -> Self {
85 Self::Document
86 }
87}