use async_trait::async_trait;
#[derive(Debug, Clone, thiserror::Error)]
pub enum OutputParserError {
#[error("Parse error: {0}")]
ParseError(String),
#[error("JSON error: {0}")]
JsonError(String),
#[error("Type error: {0}")]
TypeError(String),
#[error("{0}")]
Custom(String),
}
impl From<serde_json::Error> for OutputParserError {
fn from(e: serde_json::Error) -> Self {
OutputParserError::JsonError(e.to_string())
}
}
pub type OutputParserResult<T> = Result<T, OutputParserError>;
#[async_trait]
pub trait BaseOutputParser<Output: Send + Sync + 'static>: Send + Sync {
async fn parse(&self, text: &str) -> OutputParserResult<Output>;
async fn parse_with_retry(&self, text: &str, max_retries: usize) -> OutputParserResult<Output> {
let mut last_err = None;
for _ in 0..=max_retries {
match self.parse(text).await {
Ok(output) => return Ok(output),
Err(e) => last_err = Some(e),
}
}
Err(last_err.unwrap_or_else(|| {
OutputParserError::ParseError("parse_with_retry made no parse attempts".to_string())
}))
}
fn get_format_instructions(&self) -> String {
String::new()
}
}