gproxy_protocol/protocol/openai/audio/
stream.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize, de};
4use serde_json::Value;
5
6use super::super::common::Extra;
7use super::{AudioTokenUsage, TranscriptionLanguage, TranscriptionLogprob};
8
9#[derive(Debug, Clone, PartialEq, Serialize)]
10#[serde(untagged)]
11#[non_exhaustive]
12pub enum TranscriptionStreamEvent {
13 Known(KnownTranscriptionStreamEvent),
14 Unknown(UnknownTranscriptionStreamEvent),
15}
16
17impl<'de> Deserialize<'de> for TranscriptionStreamEvent {
18 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
19 let value = Value::deserialize(deserializer)?;
20 match value.get("type").and_then(Value::as_str) {
21 Some("transcript.text.delta" | "transcript.text.done" | "transcript.text.segment") => {
22 if let Ok(event) = serde_json::from_value(value.clone()) {
23 return Ok(Self::Known(event));
24 }
25 serde_json::from_value(value)
26 .map(Self::Unknown)
27 .map_err(de::Error::custom)
28 }
29 _ => serde_json::from_value(value)
30 .map(Self::Unknown)
31 .map_err(de::Error::custom),
32 }
33 }
34}
35
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37#[serde(tag = "type")]
38#[non_exhaustive]
39pub enum KnownTranscriptionStreamEvent {
40 #[serde(rename = "transcript.text.delta")]
41 TextDelta {
42 delta: String,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 logprobs: Option<Vec<TranscriptionLogprob>>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 segment_id: Option<String>,
47 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
48 extra: Extra,
49 },
50 #[serde(rename = "transcript.text.done")]
51 TextDone {
52 text: String,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 languages: Option<Vec<TranscriptionLanguage>>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 logprobs: Option<Vec<TranscriptionLogprob>>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 usage: Option<AudioTokenUsage>,
59 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
60 extra: Extra,
61 },
62 #[serde(rename = "transcript.text.segment")]
63 TextSegment {
64 id: String,
65 end: f64,
66 speaker: String,
67 start: f64,
68 text: String,
69 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
70 extra: Extra,
71 },
72}
73
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder)]
75#[non_exhaustive]
76pub struct UnknownTranscriptionStreamEvent {
77 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
78 pub type_: Option<String>,
79 #[serde(default, flatten, skip_serializing_if = "BTreeMap::is_empty")]
80 pub extra: Extra,
81}