use crate::mqtt4::QoS;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PacketIdentifier(pub u16);
impl From<u16> for PacketIdentifier {
fn from(value: u16) -> Self {
PacketIdentifier(value)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Protocol {
MQTT(u8),
}
#[derive(Clone, PartialEq)]
pub struct Connect {
pub protocol: Protocol,
pub keep_alive: u16,
pub client_id: String,
pub clean_session: bool,
pub last_will: Option<LastWill>,
pub username: Option<String>,
pub password: Option<String>,
}
impl Connect {
pub fn new<S: Into<String>>(id: S) -> Connect {
Connect {
protocol: Protocol::MQTT(4),
keep_alive: 10,
client_id: id.into(),
clean_session: true,
last_will: None,
username: None,
password: None,
}
}
pub fn set_username<S: Into<String>>(&mut self, u: S) -> &mut Connect {
self.username = Some(u.into());
self
}
pub fn set_password<S: Into<String>>(&mut self, p: S) -> &mut Connect {
self.password = Some(p.into());
self
}
pub(crate) fn len(&self) -> usize {
let mut len = 8 + "MQTT".len() + self.client_id.len();
if let Some(ref last_will) = self.last_will {
len += 4 + last_will.topic.len() + last_will.message.len();
}
if let Some(ref username) = self.username {
len += 2 + username.len();
}
if let Some(ref password) = self.password {
len += 2 + password.len();
}
len
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
pub enum ConnectReturnCode {
Accepted = 0,
RefusedProtocolVersion,
RefusedIdentifierRejected,
ServerUnavailable,
BadUsernamePassword,
NotAuthorized,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Connack {
pub session_present: bool,
pub code: ConnectReturnCode,
}
impl Connack {
pub fn new(code: ConnectReturnCode, session_present: bool) -> Connack {
Connack { code, session_present }
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct LastWill {
pub topic: String,
pub message: String,
pub qos: QoS,
pub retain: bool,
}
#[derive(Clone, PartialEq)]
pub struct Publish {
pub dup: bool,
pub qos: QoS,
pub retain: bool,
pub topic_name: String,
pub pkid: Option<PacketIdentifier>,
pub payload: Vec<u8>,
}
impl Publish {
pub fn new<S: Into<String>, P: Into<Vec<u8>>>(topic: S, qos: QoS, payload: P) -> Publish {
Publish {
dup: false,
qos,
retain: false,
pkid: None,
topic_name: topic.into(),
payload: payload.into(),
}
}
pub fn set_pkid<P: Into<PacketIdentifier>>(&mut self, pkid: P) -> &mut Self {
self.pkid = Some(pkid.into());
self
}
pub fn set_retain(&mut self, retain: bool) -> &mut Self {
self.retain = retain;
self
}
}
#[derive(Clone, PartialEq)]
pub struct Subscribe {
pub pkid: PacketIdentifier,
pub topics: Vec<SubscribeTopic>,
}
impl Subscribe {
pub fn new<S: Into<String>>(topic: S, qos: QoS) -> Subscribe {
let topic = SubscribeTopic {
topic_path: topic.into(),
qos,
};
Subscribe {
pkid: PacketIdentifier(0),
topics: vec![topic],
}
}
pub fn empty_subscribe() -> Subscribe {
Subscribe {
pkid: PacketIdentifier(0),
topics: Vec::new(),
}
}
pub fn add(&mut self, topic: String, qos: QoS) -> &mut Self {
let topic = SubscribeTopic { topic_path: topic, qos };
self.topics.push(topic);
self
}
}
#[derive(Clone, PartialEq)]
pub struct SubscribeTopic {
pub topic_path: String,
pub qos: QoS,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SubscribeReturnCodes {
Success(QoS),
Failure,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Suback {
pub pkid: PacketIdentifier,
pub return_codes: Vec<SubscribeReturnCodes>,
}
impl Suback {
pub fn new(pkid: PacketIdentifier, return_codes: Vec<SubscribeReturnCodes>) -> Suback {
Suback { pkid, return_codes }
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Unsubscribe {
pub pkid: PacketIdentifier,
pub topics: Vec<String>,
}
impl fmt::Debug for Publish {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Topic = {}, Qos = {:?}, Retain = {}, Pkid = {:?}, Payload Size = {}",
self.topic_name,
self.qos,
self.retain,
self.pkid,
self.payload.len()
)
}
}
impl fmt::Debug for Connect {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Protocol = {:?}, Keep alive = {:?}, Client id = {}, Clean session = {}",
self.protocol, self.keep_alive, self.client_id, self.clean_session,
)
}
}
impl fmt::Debug for Subscribe {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Filters = {:?}, Packet id = {:?}", self.pkid, self.topics)
}
}
impl fmt::Debug for SubscribeTopic {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Filter = {}, Qos = {:?}", self.topic_path, self.qos)
}
}