reasoning_parser/
traits.rs1use std::fmt;
2
3#[derive(Debug, Clone, Default, PartialEq)]
5pub struct ParserResult {
6 pub normal_text: String,
8
9 pub reasoning_text: String,
11}
12
13impl ParserResult {
14 pub fn new(normal_text: String, reasoning_text: String) -> Self {
16 Self {
17 normal_text,
18 reasoning_text,
19 }
20 }
21
22 pub fn normal(text: String) -> Self {
24 Self {
25 normal_text: text,
26 reasoning_text: String::new(),
27 }
28 }
29
30 pub fn reasoning(text: String) -> Self {
32 Self {
33 normal_text: String::new(),
34 reasoning_text: text,
35 }
36 }
37
38 pub fn is_empty(&self) -> bool {
40 self.normal_text.is_empty() && self.reasoning_text.is_empty()
41 }
42}
43
44pub trait ReasoningParser: Send + Sync {
46 fn detect_and_parse_reasoning(&mut self, text: &str) -> Result<ParserResult, ParseError>;
53
54 fn parse_reasoning_streaming_incremental(
61 &mut self,
62 text: &str,
63 ) -> Result<ParserResult, ParseError>;
64
65 fn reset(&mut self);
69
70 fn model_type(&self) -> &str;
72
73 fn is_in_reasoning(&self) -> bool;
77}
78
79#[derive(Debug, thiserror::Error)]
81pub enum ParseError {
82 #[error("Invalid UTF-8 in stream: {0}")]
83 Utf8Error(#[from] std::str::Utf8Error),
84
85 #[error("Buffer overflow: {0} bytes exceeds maximum")]
86 BufferOverflow(usize),
87
88 #[error("Unknown model type: {0}")]
89 UnknownModel(String),
90
91 #[error("Parser configuration error: {0}")]
92 ConfigError(String),
93}
94
95pub const DEFAULT_MAX_BUFFER_SIZE: usize = 4 * 1024 * 1024;
97
98#[derive(Debug, Clone)]
100pub struct ParserConfig {
101 pub think_start_token: String,
103
104 pub think_end_token: String,
106
107 pub stream_reasoning: bool,
109
110 pub max_buffer_size: usize,
112
113 pub initial_in_reasoning: bool,
115}
116
117impl Default for ParserConfig {
118 fn default() -> Self {
119 Self {
120 think_start_token: "<think>".to_string(),
121 think_end_token: "</think>".to_string(),
122 stream_reasoning: true,
123 max_buffer_size: DEFAULT_MAX_BUFFER_SIZE,
124 initial_in_reasoning: false, }
126 }
127}
128
129impl fmt::Display for ParserResult {
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 write!(
132 f,
133 "ParserResult {{ normal: {} chars, reasoning: {} chars }}",
134 self.normal_text.len(),
135 self.reasoning_text.len()
136 )
137 }
138}