use serde::{Deserialize, Serialize};
use tokio_tungstenite::tungstenite::Message;
use super::item::Item;
use super::session_resource::SessionResource;
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct SessionUpdateEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
pub session: SessionResource,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct InputAudioBufferAppendEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
pub audio: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct InputAudioBufferCommitEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct InputAudioBufferClearEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ConversationItemCreateEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub previous_item_id: Option<String>,
pub item: Item,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct ConversationItemTruncateEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
pub item_id: String,
pub content_index: u32,
pub audio_end_ms: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct ConversationItemDeleteEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
pub item_id: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct ResponseCreateEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
pub response: Option<SessionResource>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct ResponseCancelEvent {
#[serde(skip_serializing_if = "Option::is_none")]
pub event_id: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum ClientEvent {
#[serde(rename = "session.update")]
SessionUpdate(SessionUpdateEvent),
#[serde(rename = "input_audio_buffer.append")]
InputAudioBufferAppend(InputAudioBufferAppendEvent),
#[serde(rename = "input_audio_buffer.commit")]
InputAudioBufferCommit(InputAudioBufferCommitEvent),
#[serde(rename = "input_audio_buffer.clear")]
InputAudioBufferClear(InputAudioBufferClearEvent),
#[serde(rename = "conversation.item.create")]
ConversationItemCreate(ConversationItemCreateEvent),
#[serde(rename = "conversation.item.truncate")]
ConversationItemTruncate(ConversationItemTruncateEvent),
#[serde(rename = "conversation.item.delete")]
ConversationItemDelete(ConversationItemDeleteEvent),
#[serde(rename = "response.create")]
ResponseCreate(ResponseCreateEvent),
#[serde(rename = "response.cancel")]
ResponseCancel(ResponseCancelEvent),
}
impl From<&ClientEvent> for String {
fn from(value: &ClientEvent) -> Self {
serde_json::to_string(value).unwrap()
}
}
impl From<ClientEvent> for Message {
fn from(value: ClientEvent) -> Self {
Message::Text(String::from(&value).into())
}
}
macro_rules! message_from_event {
($from_typ:ty, $evt_typ:ty) => {
impl From<$from_typ> for Message {
fn from(value: $from_typ) -> Self {
Self::from(<$evt_typ>::from(value))
}
}
};
}
macro_rules! event_from {
($from_typ:ty, $evt_typ:ty, $variant:ident) => {
impl From<$from_typ> for $evt_typ {
fn from(value: $from_typ) -> Self {
<$evt_typ>::$variant(value)
}
}
};
}
event_from!(SessionUpdateEvent, ClientEvent, SessionUpdate);
event_from!(
InputAudioBufferAppendEvent,
ClientEvent,
InputAudioBufferAppend
);
event_from!(
InputAudioBufferCommitEvent,
ClientEvent,
InputAudioBufferCommit
);
event_from!(
InputAudioBufferClearEvent,
ClientEvent,
InputAudioBufferClear
);
event_from!(
ConversationItemCreateEvent,
ClientEvent,
ConversationItemCreate
);
event_from!(
ConversationItemTruncateEvent,
ClientEvent,
ConversationItemTruncate
);
event_from!(
ConversationItemDeleteEvent,
ClientEvent,
ConversationItemDelete
);
event_from!(ResponseCreateEvent, ClientEvent, ResponseCreate);
event_from!(ResponseCancelEvent, ClientEvent, ResponseCancel);
message_from_event!(SessionUpdateEvent, ClientEvent);
message_from_event!(InputAudioBufferAppendEvent, ClientEvent);
message_from_event!(InputAudioBufferCommitEvent, ClientEvent);
message_from_event!(InputAudioBufferClearEvent, ClientEvent);
message_from_event!(ConversationItemCreateEvent, ClientEvent);
message_from_event!(ConversationItemTruncateEvent, ClientEvent);
message_from_event!(ConversationItemDeleteEvent, ClientEvent);
message_from_event!(ResponseCreateEvent, ClientEvent);
message_from_event!(ResponseCancelEvent, ClientEvent);
impl From<Item> for ConversationItemCreateEvent {
fn from(value: Item) -> Self {
Self {
event_id: None,
previous_item_id: None,
item: value,
}
}
}