use serde_json::{Map, Value, json};
use super::{Delta, Stream};
const TEXT: &str = "text";
const THINKING: &str = "thinking";
pub fn stream_value(stream: &Stream) -> Value {
let mut map = Map::new();
if let Some(text) = &stream.text {
map.insert(TEXT.to_owned(), json!(text));
}
if let Some(thinking) = &stream.thinking {
map.insert(THINKING.to_owned(), json!(thinking));
}
if let Some(delta) = stream.last_delta {
map.insert("delta".to_owned(), json!(token(delta)));
}
Value::Object(map)
}
pub fn stream_of(o: &Map<String, Value>) -> Result<Stream, String> {
use crate::boundary::codec::fields::opt_str_of;
Ok(Stream {
text: opt_str_of(o, TEXT)?,
thinking: opt_str_of(o, THINKING)?,
last_delta: match opt_str_of(o, "delta")?.as_deref() {
None => None,
Some(TEXT) => Some(Delta::Text),
Some(THINKING) => Some(Delta::Thinking),
Some(other) => return Err(format!("stream: unknown delta kind {other:?}")),
},
})
}
fn token(delta: Delta) -> &'static str {
match delta {
Delta::Text => TEXT,
Delta::Thinking => THINKING,
}
}