streamdown_core/
enums.rs

1//! Core enums for streamdown parsing state.
2//!
3//! These enums represent the various states that the parser can be in
4//! while processing streaming markdown input.
5
6use serde::{Deserialize, Serialize};
7
8/// Represents the type of code block or code-related state.
9///
10/// This enum tracks whether we're in a fenced code block (backticks),
11/// an indented code block (spaces), or processing table sections.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub enum Code {
14    /// Code block defined by leading spaces (indented code)
15    Spaces,
16    /// Code block defined by backtick fence (```)
17    Backtick,
18    /// Table header row
19    Header,
20    /// Table body rows
21    Body,
22    /// Flush/reset state
23    Flush,
24}
25
26impl std::fmt::Display for Code {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        match self {
29            Code::Spaces => write!(f, "spaces"),
30            Code::Backtick => write!(f, "backtick"),
31            Code::Header => write!(f, "header"),
32            Code::Body => write!(f, "body"),
33            Code::Flush => write!(f, "flush"),
34        }
35    }
36}
37
38/// Represents the type of list being processed.
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
40pub enum ListType {
41    /// Unordered list with bullets (*, -, +)
42    Bullet,
43    /// Ordered list with numbers (1., 2., etc.)
44    Ordered,
45}
46
47impl std::fmt::Display for ListType {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match self {
50            ListType::Bullet => write!(f, "bullet"),
51            ListType::Ordered => write!(f, "ordered"),
52        }
53    }
54}
55
56/// Represents the current section of a table being processed.
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
58pub enum TableState {
59    /// Processing table header row
60    Header,
61    /// Processing table body rows
62    Body,
63}
64
65impl std::fmt::Display for TableState {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        match self {
68            TableState::Header => write!(f, "header"),
69            TableState::Body => write!(f, "body"),
70        }
71    }
72}
73
74/// Represents the type of block-level element being processed.
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
76pub enum BlockType {
77    /// Block quote (> prefix)
78    Quote,
79    /// "Think" block (special AI thinking sections)
80    Think,
81}
82
83impl std::fmt::Display for BlockType {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        match self {
86            BlockType::Quote => write!(f, "quote"),
87            BlockType::Think => write!(f, "think"),
88        }
89    }
90}
91
92/// Flags for special emit behavior.
93///
94/// These flags signal to the renderer that special handling is needed
95/// for the current output.
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
97pub enum EmitFlag {
98    /// Emit as level 1 header
99    Header1,
100    /// Emit as level 2 header
101    Header2,
102    /// Flush output immediately
103    Flush,
104}
105
106impl std::fmt::Display for EmitFlag {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108        match self {
109            EmitFlag::Header1 => write!(f, "header1"),
110            EmitFlag::Header2 => write!(f, "header2"),
111            EmitFlag::Flush => write!(f, "flush"),
112        }
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    use super::*;
119
120    #[test]
121    fn test_code_display() {
122        assert_eq!(Code::Spaces.to_string(), "spaces");
123        assert_eq!(Code::Backtick.to_string(), "backtick");
124        assert_eq!(Code::Header.to_string(), "header");
125        assert_eq!(Code::Body.to_string(), "body");
126        assert_eq!(Code::Flush.to_string(), "flush");
127    }
128
129    #[test]
130    fn test_list_type_display() {
131        assert_eq!(ListType::Bullet.to_string(), "bullet");
132        assert_eq!(ListType::Ordered.to_string(), "ordered");
133    }
134
135    #[test]
136    fn test_table_state_display() {
137        assert_eq!(TableState::Header.to_string(), "header");
138        assert_eq!(TableState::Body.to_string(), "body");
139    }
140
141    #[test]
142    fn test_block_type_display() {
143        assert_eq!(BlockType::Quote.to_string(), "quote");
144        assert_eq!(BlockType::Think.to_string(), "think");
145    }
146
147    #[test]
148    fn test_emit_flag_display() {
149        assert_eq!(EmitFlag::Header1.to_string(), "header1");
150        assert_eq!(EmitFlag::Header2.to_string(), "header2");
151        assert_eq!(EmitFlag::Flush.to_string(), "flush");
152    }
153}