use crate::normalized::ContentFrame;
pub trait ModelResponseParser: Send + Sync {
fn supported_models(&self) -> Vec<String>;
fn parse(&self, raw_response: &str) -> Result<ContentFrame, ParseError>;
fn can_handle(&self, model: &str) -> bool {
self.supported_models().iter().any(|m| m == model)
}
}
#[derive(Debug, thiserror::Error)]
pub enum ParseError {
#[error("Invalid JSON: {0}")]
InvalidJson(#[from] serde_json::Error),
#[error("Missing field: {0}")]
MissingField(String),
#[error("Unsupported model: {0}")]
UnsupportedModel(String),
#[error("Parsing error: {0}")]
Other(String),
}
#[cfg(test)]
mod tests {
use super::*;
use crate::normalized::{ContentBlock, ContentFrame};
struct MockParser {
supported: Vec<String>,
}
impl ModelResponseParser for MockParser {
fn supported_models(&self) -> Vec<String> {
self.supported.clone()
}
fn parse(&self, raw_response: &str) -> Result<ContentFrame, ParseError> {
if !raw_response.contains("mock") {
return Err(ParseError::Other("Expected mock in response".to_string()));
}
Ok(ContentFrame {
id: "mock_id".to_string(),
model: "mock_model".to_string(),
blocks: vec![ContentBlock::Text {
text: "Mocked response".to_string(),
}],
})
}
}
#[test]
fn test_can_handle() {
let parser = MockParser {
supported: vec!["model1".to_string(), "model2".to_string()],
};
assert!(parser.can_handle("model1"));
assert!(parser.can_handle("model2"));
assert!(!parser.can_handle("model3"));
}
#[test]
fn test_parse_success() {
let parser = MockParser {
supported: vec!["mock_model".to_string()],
};
let result = parser.parse("mock response data");
assert!(result.is_ok());
let frame = result.unwrap();
assert_eq!(frame.id, "mock_id");
assert_eq!(frame.model, "mock_model");
assert_eq!(frame.blocks.len(), 1);
}
#[test]
fn test_parse_error() {
let parser = MockParser {
supported: vec!["mock_model".to_string()],
};
let result = parser.parse("not containing expected keyword");
assert!(result.is_err());
match result.unwrap_err() {
ParseError::Other(msg) => assert_eq!(msg, "Expected mock in response"),
_ => panic!("Expected Other error variant"),
}
}
}