use core::fmt;
use serde::ser::{SerializeStruct, Serializer};
use serde::Serialize;
use crate::mqtt::packet::GenericPacket;
use crate::mqtt::packet::IsPacketId;
use crate::mqtt::result_code::MqttError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum TimerKind {
#[serde(rename = "pingreq_send")]
PingreqSend,
#[serde(rename = "pingreq_recv")]
PingreqRecv,
#[serde(rename = "pingresp_recv")]
PingrespRecv,
}
#[derive(Clone)]
pub enum GenericEvent<PacketIdType>
where
PacketIdType: IsPacketId + Serialize + 'static,
{
NotifyPacketReceived(GenericPacket<PacketIdType>),
RequestSendPacket {
packet: GenericPacket<PacketIdType>,
release_packet_id_if_send_error: Option<PacketIdType>,
},
NotifyPacketIdReleased(PacketIdType),
RequestTimerReset {
kind: TimerKind,
duration_ms: u64,
},
RequestTimerCancel(TimerKind),
NotifyError(MqttError),
RequestClose,
}
pub type Event = GenericEvent<u16>;
impl<PacketIdType> Serialize for GenericEvent<PacketIdType>
where
PacketIdType: IsPacketId + Serialize + 'static,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
GenericEvent::NotifyPacketReceived(packet) => {
let mut state = serializer.serialize_struct("GenericEvent", 2)?;
state.serialize_field("type", "notify_packet_received")?;
state.serialize_field("packet", packet)?;
state.end()
}
GenericEvent::RequestSendPacket {
packet,
release_packet_id_if_send_error,
} => {
let mut state = serializer.serialize_struct("GenericEvent", 3)?;
state.serialize_field("type", "request_send_packet")?;
state.serialize_field("packet", packet)?;
state.serialize_field(
"release_packet_id_if_send_error",
release_packet_id_if_send_error,
)?;
state.end()
}
GenericEvent::NotifyPacketIdReleased(packet_id) => {
let mut state = serializer.serialize_struct("GenericEvent", 2)?;
state.serialize_field("type", "notify_packet_id_released")?;
state.serialize_field("packet_id", packet_id)?;
state.end()
}
GenericEvent::RequestTimerReset { kind, duration_ms } => {
let mut state = serializer.serialize_struct("GenericEvent", 3)?;
state.serialize_field("type", "request_timer_reset")?;
state.serialize_field("kind", kind)?;
state.serialize_field("duration_ms", duration_ms)?;
state.end()
}
GenericEvent::RequestTimerCancel(kind) => {
let mut state = serializer.serialize_struct("GenericEvent", 2)?;
state.serialize_field("type", "request_timer_cancel")?;
state.serialize_field("kind", kind)?;
state.end()
}
GenericEvent::NotifyError(error) => {
let mut state = serializer.serialize_struct("GenericEvent", 2)?;
state.serialize_field("type", "notify_error")?;
state.serialize_field("error", &format!("{error:?}"))?;
state.end()
}
GenericEvent::RequestClose => {
let mut state = serializer.serialize_struct("GenericEvent", 1)?;
state.serialize_field("type", "request_close")?;
state.end()
}
}
}
}
impl<PacketIdType> fmt::Display for GenericEvent<PacketIdType>
where
PacketIdType: IsPacketId + Serialize + 'static,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match serde_json::to_string(self) {
Ok(json) => write!(f, "{json}"),
Err(e) => write!(f, "{{\"error\": \"{e}\"}}"),
}
}
}
impl<PacketIdType> fmt::Debug for GenericEvent<PacketIdType>
where
PacketIdType: IsPacketId + Serialize + 'static,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}