#[derive(Debug, Clone)]
pub enum StreamEvent {
TextDelta(String),
InputJsonDelta(String),
Done,
Error(String),
}
#[derive(Debug, Default)]
pub struct StreamAccumulator {
text: String,
}
impl StreamAccumulator {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, event: &StreamEvent) {
if let StreamEvent::TextDelta(delta) = event {
self.text.push_str(delta);
}
}
pub fn text(&self) -> &str {
&self.text
}
pub fn into_text(self) -> String {
self.text
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn accumulates_text_deltas() {
let mut acc = StreamAccumulator::new();
acc.push(&StreamEvent::TextDelta("Hello".to_string()));
acc.push(&StreamEvent::TextDelta(", world".to_string()));
acc.push(&StreamEvent::Done);
assert_eq!(acc.text(), "Hello, world");
}
#[test]
fn ignores_non_text_events() {
let mut acc = StreamAccumulator::new();
acc.push(&StreamEvent::InputJsonDelta("{\"foo\":".to_string()));
acc.push(&StreamEvent::Done);
assert_eq!(acc.text(), "");
}
#[test]
fn into_text_consumes() {
let mut acc = StreamAccumulator::new();
acc.push(&StreamEvent::TextDelta("hi".to_string()));
assert_eq!(acc.into_text(), "hi");
}
}