use std::time::Duration;
#[cfg(feature = "server-logic")]
use axum::extract::ws;
use serde::{Deserialize, Serialize};
use crate::common::chunk;
use crate::common::chunk::{Chunk, ChunkId};
use crate::common::errors::{IncorrectUsage, LimitIsZero};
use crate::common::submission::Submission;
use crate::consumer::strategy::Strategy;
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub enum ClientToServerMessage {
WantToReserveChunks {
max: usize,
strategy: Strategy,
},
CompleteChunk {
id: ChunkId,
output_content: chunk::Content,
},
FailChunk {
id: ChunkId,
failure: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ServerToClientMessage {
Sync(Envelope<SyncServerToClientResponse>),
Async(AsyncServerToClientMessage),
Init(ConsumerConfig),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SyncServerToClientResponse {
#[allow(clippy::type_complexity)]
ChunksReserved(Result<Vec<(Chunk, Submission)>, IncorrectUsage<LimitIsZero>>),
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub enum AsyncServerToClientMessage {
ChunkReservationExpired(ChunkId),
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Envelope<T> {
pub nonce: usize,
pub contents: T,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsumerConfig {
pub max_missable_heartbeats: usize,
pub heartbeat_interval: Duration,
pub version_info: String,
pub conn_id: String,
}
#[cfg(feature = "server-logic")]
impl TryFrom<ws::Message> for Envelope<ClientToServerMessage> {
type Error = ciborium::de::Error<std::io::Error>;
fn try_from(value: ws::Message) -> Result<Self, Self::Error> {
ciborium::from_reader(&*value.into_data())
}
}
#[cfg(feature = "server-logic")]
impl TryFrom<ws::Message> for ServerToClientMessage {
type Error = ciborium::de::Error<std::io::Error>;
fn try_from(value: ws::Message) -> Result<Self, Self::Error> {
ciborium::from_reader(&*value.into_data())
}
}
#[cfg(feature = "server-logic")]
impl From<ServerToClientMessage> for ws::Message {
fn from(val: ServerToClientMessage) -> Self {
let mut writer = Vec::new();
ciborium::into_writer(&val, &mut writer)
.expect("Failed to serialize ServerToClientMessage");
ws::Message::Binary(writer)
}
}
#[cfg(feature = "server-logic")]
impl From<Envelope<ClientToServerMessage>> for ws::Message {
fn from(val: Envelope<ClientToServerMessage>) -> Self {
let mut writer = Vec::new();
ciborium::into_writer(&val, &mut writer)
.expect("Failed to serialize ClientToServerMessage");
ws::Message::Binary(writer)
}
}
#[cfg(feature = "client-logic")]
impl TryFrom<tokio_tungstenite::tungstenite::Message> for Envelope<ClientToServerMessage> {
type Error = ciborium::de::Error<std::io::Error>;
fn try_from(value: tokio_tungstenite::tungstenite::Message) -> Result<Self, Self::Error> {
ciborium::from_reader(&*value.into_data())
}
}
#[cfg(feature = "client-logic")]
impl TryFrom<tokio_tungstenite::tungstenite::Message> for ServerToClientMessage {
type Error = ciborium::de::Error<std::io::Error>;
fn try_from(value: tokio_tungstenite::tungstenite::Message) -> Result<Self, Self::Error> {
ciborium::from_reader(&*value.into_data())
}
}
#[cfg(feature = "client-logic")]
impl From<ServerToClientMessage> for tokio_tungstenite::tungstenite::Message {
fn from(val: ServerToClientMessage) -> Self {
let mut writer = Vec::new();
ciborium::into_writer(&val, &mut writer)
.expect("Failed to serialize ServerToClientMessage");
tokio_tungstenite::tungstenite::Message::Binary(writer)
}
}
#[cfg(feature = "client-logic")]
impl From<Envelope<ClientToServerMessage>> for tokio_tungstenite::tungstenite::Message {
fn from(val: Envelope<ClientToServerMessage>) -> Self {
let mut writer = Vec::new();
ciborium::into_writer(&val, &mut writer)
.expect("Failed to serialize ClientToServerMessage");
tokio_tungstenite::tungstenite::Message::Binary(writer)
}
}