use crate::Error;
use crate::codec::{Decode, Encode, RawPacket};
use crate::protocol::PacketType;
use crate::protocol::v5::{
Auth, ConnAck, Connect, Disconnect, PingReq, PingResp, PubAck, PubComp, PubRec, PubRel,
Publish, SubAck, Subscribe, UnsubAck, Unsubscribe,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Packet {
Connect(Connect),
ConnAck(ConnAck),
Publish(Publish),
PubAck(PubAck),
PubRec(PubRec),
PubRel(PubRel),
PubComp(PubComp),
Subscribe(Subscribe),
SubAck(SubAck),
Unsubscribe(Unsubscribe),
UnsubAck(UnsubAck),
PingReq(PingReq),
PingResp(PingResp),
Disconnect(Disconnect),
Auth(Auth),
}
impl Packet {
pub fn decode(raw_packet: RawPacket) -> Result<Self, Error> {
let packet_type = raw_packet.header.packet_type();
if raw_packet.header.remaining_len() == 0 {
return match packet_type {
PacketType::PingReq => Ok(Self::PingReq(PingReq::decode(raw_packet)?)),
PacketType::PingResp => Ok(Self::PingResp(PingResp::decode(raw_packet)?)),
PacketType::Disconnect => Ok(Self::Disconnect(Disconnect::decode(raw_packet)?)),
PacketType::Auth => Ok(Self::Auth(Auth::decode(raw_packet)?)),
_ => Err(Error::PayloadRequired),
};
}
let decoded = match packet_type {
PacketType::Connect => Self::Connect(Connect::decode(raw_packet)?),
PacketType::ConnAck => Self::ConnAck(ConnAck::decode(raw_packet)?),
PacketType::Publish => Self::Publish(Publish::decode(raw_packet)?),
PacketType::PubAck => Self::PubAck(PubAck::decode(raw_packet)?),
PacketType::PubRec => Self::PubRec(PubRec::decode(raw_packet)?),
PacketType::PubRel => Self::PubRel(PubRel::decode(raw_packet)?),
PacketType::PubComp => Self::PubComp(PubComp::decode(raw_packet)?),
PacketType::Subscribe => Self::Subscribe(Subscribe::decode(raw_packet)?),
PacketType::SubAck => Self::SubAck(SubAck::decode(raw_packet)?),
PacketType::Unsubscribe => Self::Unsubscribe(Unsubscribe::decode(raw_packet)?),
PacketType::UnsubAck => Self::UnsubAck(UnsubAck::decode(raw_packet)?),
PacketType::Disconnect => Self::Disconnect(Disconnect::decode(raw_packet)?),
PacketType::Auth => Self::Auth(Auth::decode(raw_packet)?),
_ => return Err(Error::MalformedPacket),
};
Ok(decoded)
}
pub fn encode(&self, buf: &mut bytes::BytesMut) -> Result<(), Error> {
match self {
Self::Connect(packet) => packet.encode(buf),
Self::ConnAck(packet) => packet.encode(buf),
Self::Publish(packet) => packet.encode(buf),
Self::PubAck(packet) => packet.encode(buf),
Self::PubRec(packet) => packet.encode(buf),
Self::PubRel(packet) => packet.encode(buf),
Self::PubComp(packet) => packet.encode(buf),
Self::Subscribe(packet) => packet.encode(buf),
Self::SubAck(packet) => packet.encode(buf),
Self::Unsubscribe(packet) => packet.encode(buf),
Self::UnsubAck(packet) => packet.encode(buf),
Self::PingReq(packet) => packet.encode(buf),
Self::PingResp(packet) => packet.encode(buf),
Self::Disconnect(packet) => packet.encode(buf),
Self::Auth(packet) => packet.encode(buf),
}
}
}
impl From<Connect> for Packet {
fn from(value: Connect) -> Self {
Self::Connect(value)
}
}
impl From<ConnAck> for Packet {
fn from(value: ConnAck) -> Self {
Self::ConnAck(value)
}
}
impl From<Publish> for Packet {
fn from(value: Publish) -> Self {
Self::Publish(value)
}
}
impl From<PubAck> for Packet {
fn from(value: PubAck) -> Self {
Self::PubAck(value)
}
}
impl From<PubRec> for Packet {
fn from(value: PubRec) -> Self {
Self::PubRec(value)
}
}
impl From<PubRel> for Packet {
fn from(value: PubRel) -> Self {
Self::PubRel(value)
}
}
impl From<PubComp> for Packet {
fn from(value: PubComp) -> Self {
Self::PubComp(value)
}
}
impl From<Subscribe> for Packet {
fn from(value: Subscribe) -> Self {
Self::Subscribe(value)
}
}
impl From<SubAck> for Packet {
fn from(value: SubAck) -> Self {
Self::SubAck(value)
}
}
impl From<Unsubscribe> for Packet {
fn from(value: Unsubscribe) -> Self {
Self::Unsubscribe(value)
}
}
impl From<UnsubAck> for Packet {
fn from(value: UnsubAck) -> Self {
Self::UnsubAck(value)
}
}
impl From<PingReq> for Packet {
fn from(value: PingReq) -> Self {
Self::PingReq(value)
}
}
impl From<PingResp> for Packet {
fn from(value: PingResp) -> Self {
Self::PingResp(value)
}
}
impl From<Disconnect> for Packet {
fn from(value: Disconnect) -> Self {
Self::Disconnect(value)
}
}
impl From<Auth> for Packet {
fn from(value: Auth) -> Self {
Self::Auth(value)
}
}