use super::SseFrame;
use crate::model::TransformError;
pub(crate) enum ParsedAnthropicEvent {
Done,
Event {
event_type: String,
payload: serde_json::Value,
},
}
pub(crate) fn parse_anthropic_stream_frames<'a>(
frames: impl IntoIterator<Item = &'a SseFrame>,
) -> impl Iterator<Item = Result<ParsedAnthropicEvent, TransformError>> {
frames.into_iter().filter_map(|frame| {
let data = frame.data.trim();
if data.is_empty() {
return None;
}
if data == "[DONE]" {
return Some(Ok(ParsedAnthropicEvent::Done));
}
let payload: serde_json::Value = match serde_json::from_str(data) {
Ok(v) => v,
Err(e) => {
return Some(Err(TransformError::InvalidFormat(format!(
"Anthropic chunk parse: {e}"
))));
}
};
let payload_type = payload
.get("type")
.and_then(serde_json::Value::as_str)
.map(str::to_owned);
let event_type = match frame.event.as_deref().or(payload_type.as_deref()) {
Some(t) => t.to_owned(),
None => {
return Some(Err(TransformError::MissingRequiredField(
"stream event type".to_string(),
)));
}
};
Some(Ok(ParsedAnthropicEvent::Event {
event_type,
payload,
}))
})
}