use bytes::Bytes;
use futures::Stream;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::errors::UpstreamError;
pub enum ChatResponse {
NonStreaming(Value),
Streaming(Box<dyn Stream<Item = Result<Bytes, UpstreamError>> + Send + Unpin>),
}
impl std::fmt::Debug for ChatResponse {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ChatResponse::NonStreaming(v) => f.debug_tuple("NonStreaming").field(v).finish(),
ChatResponse::Streaming(_) => {
f.debug_tuple("Streaming").field(&"<byte stream>").finish()
}
}
}
}
impl Serialize for ChatResponse {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
ChatResponse::NonStreaming(v) => v.serialize(serializer),
ChatResponse::Streaming(_) => Err(serde::ser::Error::custom(
"cannot serialize a streaming ChatResponse; drain the stream first",
)),
}
}
}
impl<'de> Deserialize<'de> for ChatResponse {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Value::deserialize(deserializer).map(ChatResponse::NonStreaming)
}
}
#[cfg(test)]
mod tests {
use super::*;
use futures::stream;
use serde_json::json;
#[test]
fn non_streaming_serialises_inner_value() {
let resp = ChatResponse::NonStreaming(json!({"choices": []}));
let s = serde_json::to_string(&resp).unwrap();
assert!(s.contains("choices"));
}
#[test]
fn streaming_arm_is_not_serialisable() {
let stream: Box<dyn Stream<Item = Result<Bytes, UpstreamError>> + Send + Unpin> =
Box::new(stream::iter(vec![Ok(Bytes::from_static(b"chunk"))]));
let resp = ChatResponse::Streaming(stream);
let result = serde_json::to_string(&resp);
assert!(result.is_err());
}
#[test]
fn non_streaming_roundtrips_through_serde() {
let resp = ChatResponse::NonStreaming(json!({"a": 1}));
let json_str = serde_json::to_string(&resp).unwrap();
let back: ChatResponse = serde_json::from_str(&json_str).unwrap();
match back {
ChatResponse::NonStreaming(v) => assert_eq!(v["a"], 1),
ChatResponse::Streaming(_) => panic!("expected NonStreaming"),
}
}
}