rust_yaml/scanner/
state.rs

1//! Scanner state management
2
3use crate::Position;
4
5/// Scanner state for different contexts
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[allow(missing_docs)]
8pub enum ScannerState {
9    StreamStart,
10    StreamEnd,
11    DocumentStart,
12    DocumentContent,
13    BlockMapping,
14    BlockSequence,
15    FlowMapping,
16    FlowSequence,
17    Scalar,
18    Tag,
19    Anchor,
20    Alias,
21}
22
23/// Scanner context manager
24#[derive(Debug)]
25pub struct ScannerContext {
26    /// Current scanner state
27    pub state: ScannerState,
28    /// Flow level (0 = block context, >0 = flow context)
29    pub flow_level: usize,
30    /// Whether we're in a key position
31    pub in_key: bool,
32    /// Whether we're in a value position
33    pub in_value: bool,
34    /// Whether simple keys are allowed
35    pub allow_simple_key: bool,
36    /// Stack of simple key positions
37    pub simple_keys: Vec<Option<Position>>,
38}
39
40impl ScannerContext {
41    /// Create a new scanner context
42    pub fn new() -> Self {
43        Self {
44            state: ScannerState::StreamStart,
45            flow_level: 0,
46            in_key: false,
47            in_value: false,
48            allow_simple_key: true,
49            simple_keys: vec![None],
50        }
51    }
52
53    /// Reset the scanner context
54    pub fn reset(&mut self) {
55        self.state = ScannerState::StreamStart;
56        self.flow_level = 0;
57        self.in_key = false;
58        self.in_value = false;
59        self.allow_simple_key = true;
60        self.simple_keys.clear();
61        self.simple_keys.push(None);
62    }
63
64    /// Check if we're in flow context
65    pub fn in_flow(&self) -> bool {
66        self.flow_level > 0
67    }
68
69    /// Check if we're in block context
70    pub fn in_block(&self) -> bool {
71        self.flow_level == 0
72    }
73
74    /// Enter flow context
75    pub fn enter_flow(&mut self) {
76        self.flow_level += 1;
77        self.simple_keys.push(None);
78    }
79
80    /// Exit flow context
81    pub fn exit_flow(&mut self) {
82        if self.flow_level > 0 {
83            self.flow_level -= 1;
84            self.simple_keys.pop();
85        }
86    }
87
88    /// Save a simple key position
89    pub fn save_simple_key(&mut self, position: Position) {
90        if let Some(key_slot) = self.simple_keys.last_mut() {
91            *key_slot = Some(position);
92        }
93    }
94
95    /// Clear the current simple key
96    pub fn clear_simple_key(&mut self) {
97        if let Some(key_slot) = self.simple_keys.last_mut() {
98            *key_slot = None;
99        }
100    }
101
102    /// Check if a simple key is possible
103    pub fn simple_key_allowed(&self) -> bool {
104        self.allow_simple_key && self.simple_keys.last().map_or(false, |k| k.is_none())
105    }
106}
107
108impl Default for ScannerContext {
109    fn default() -> Self {
110        Self::new()
111    }
112}