use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::messages::{ControllerMessage, ServiceMessage};
use super::trace_context::TraceContext;
pub const CURRENT_PROTOCOL_VERSION: u32 = 1;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct ReportPagination {
pub report_id: Uuid,
pub page: u32,
pub total_pages: u32,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ServiceEnvelope {
pub protocol_version: u32,
pub seq: u64,
#[serde(default)]
pub trace_context: TraceContext,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub pagination: Option<ReportPagination>,
#[serde(flatten)]
pub message: ServiceMessage,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ControllerEnvelope {
pub protocol_version: u32,
pub seq: u64,
#[serde(default)]
pub trace_context: TraceContext,
#[serde(flatten)]
pub message: ControllerMessage,
}
#[derive(Debug)]
pub struct OutgoingSeq {
next: u64,
}
impl OutgoingSeq {
pub fn new() -> Self {
Self { next: 1 }
}
pub fn wrap_service(
&mut self,
message: ServiceMessage,
trace_context: TraceContext,
) -> ServiceEnvelope {
self.wrap_service_paginated(message, trace_context, None)
}
pub fn wrap_service_paginated(
&mut self,
message: ServiceMessage,
trace_context: TraceContext,
pagination: Option<ReportPagination>,
) -> ServiceEnvelope {
let seq = self.next;
self.next += 1;
ServiceEnvelope {
protocol_version: CURRENT_PROTOCOL_VERSION,
seq,
trace_context,
pagination,
message,
}
}
pub fn wrap_controller(
&mut self,
message: ControllerMessage,
trace_context: TraceContext,
) -> ControllerEnvelope {
let seq = self.next;
self.next += 1;
ControllerEnvelope {
protocol_version: CURRENT_PROTOCOL_VERSION,
seq,
trace_context,
message,
}
}
}
impl Default for OutgoingSeq {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct IncomingSeq {
expected: u64,
}
impl IncomingSeq {
pub fn new() -> Self {
Self { expected: 1 }
}
pub fn validate(&mut self, received: u64) -> Result<(), SeqError> {
if received != self.expected {
return Err(SeqError {
expected: self.expected,
received,
});
}
self.expected += 1;
Ok(())
}
}
impl Default for IncomingSeq {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[error("sequence error: expected {expected}, received {received}")]
pub struct SeqError {
pub expected: u64,
pub received: u64,
}