smos_application/types/
chat_response.rs1use bytes::Bytes;
11use futures::Stream;
12use serde::{Deserialize, Serialize};
13use serde_json::Value;
14
15use crate::errors::UpstreamError;
16
17pub enum ChatResponse {
23 NonStreaming(Value),
25
26 Streaming(Box<dyn Stream<Item = Result<Bytes, UpstreamError>> + Send + Unpin>),
30}
31
32impl std::fmt::Debug for ChatResponse {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 match self {
35 ChatResponse::NonStreaming(v) => f.debug_tuple("NonStreaming").field(v).finish(),
36 ChatResponse::Streaming(_) => {
37 f.debug_tuple("Streaming").field(&"<byte stream>").finish()
38 }
39 }
40 }
41}
42
43impl Serialize for ChatResponse {
47 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
48 where
49 S: serde::Serializer,
50 {
51 match self {
52 ChatResponse::NonStreaming(v) => v.serialize(serializer),
53 ChatResponse::Streaming(_) => Err(serde::ser::Error::custom(
54 "cannot serialize a streaming ChatResponse; drain the stream first",
55 )),
56 }
57 }
58}
59
60impl<'de> Deserialize<'de> for ChatResponse {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: serde::Deserializer<'de>,
66 {
67 Value::deserialize(deserializer).map(ChatResponse::NonStreaming)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use futures::stream;
75 use serde_json::json;
76
77 #[test]
78 fn non_streaming_serialises_inner_value() {
79 let resp = ChatResponse::NonStreaming(json!({"choices": []}));
80 let s = serde_json::to_string(&resp).unwrap();
81 assert!(s.contains("choices"));
82 }
83
84 #[test]
85 fn streaming_arm_is_not_serialisable() {
86 let stream: Box<dyn Stream<Item = Result<Bytes, UpstreamError>> + Send + Unpin> =
87 Box::new(stream::iter(vec![Ok(Bytes::from_static(b"chunk"))]));
88 let resp = ChatResponse::Streaming(stream);
89 let result = serde_json::to_string(&resp);
90 assert!(result.is_err());
91 }
92
93 #[test]
94 fn non_streaming_roundtrips_through_serde() {
95 let resp = ChatResponse::NonStreaming(json!({"a": 1}));
96 let json_str = serde_json::to_string(&resp).unwrap();
97 let back: ChatResponse = serde_json::from_str(&json_str).unwrap();
98 match back {
99 ChatResponse::NonStreaming(v) => assert_eq!(v["a"], 1),
100 ChatResponse::Streaming(_) => panic!("expected NonStreaming"),
101 }
102 }
103}