# `📟 mqrstt` [![Crates.io](https://img.shields.io/crates/v/mqrstt.svg)](https://crates.io/crates/mqrstt) [![Docs](https://docs.rs/mqrstt/badge.svg)](https://docs.rs/mqrstt) [![dependency status](https://deps.rs/repo/github/GunnarMorrigan/mqrstt/status.svg)](https://deps.rs/repo/github/GunnarMorrigan/mqrstt) [![codecov](https://codecov.io/github/GunnarMorrigan/mqrstt/branch/main/graph/badge.svg?token=YSZFYQ063Y)](https://codecov.io/github/GunnarMorrigan/mqrstt) `mqrstt` is an MQTTv5 client implementation that allows for the smol and tokio runtimes. In the future we will also support a sync implementation.

Examples

You want to reconnect (with a new stream) after the network encountered an error or a disconnect took place!

Smol example:

```rust use mqrstt::{ client::AsyncClient, connectoptions::ConnectOptions, newsmol, packets::{self, Packet}, AsyncEventHandlerMut, HandlerStatus, NetworkStatus, }; use asynctrait::asynctrait; use bytes::Bytes; pub struct PingPong { pub client: AsyncClient, }

[async_trait]

impl AsyncEventHandlerMut for PingPong { // Handlers only get INCOMING packets. This can change later. async fn handle(&mut self, event: &packets::Packet) -> () { match event { Packet::Publish(p) => { if let Ok(payload) = String::fromutf8(p.payload.tovec()) { if payload.tolowercase().contains("ping") { self.client .publish( p.qos, p.retain, p.topic.clone(), Bytes::fromstatic(b"pong"), ) .await .unwrap(); println!("Received Ping, Send pong!"); } } }, Packet::ConnAck() => { println!("Connected!") }, _ => (), } } } smol::blockon(async { let options = ConnectOptions::new("mqrstt".tostring()); let (mut network, mut handler, client) = newsmol(options); let stream = smol::net::TcpStream::connect(("broker.emqx.io", 1883)).await.unwrap(); network.connect(stream).await.unwrap(); client.subscribe("mqrstt").await.unwrap(); let mut pingpong = PingPong { client: client.clone(), }; let (n, h, t) = futures::join!( async { loop { return match network.run().await { Ok(NetworkStatus::Active) => continue, otherwise => otherwise, }; } }, async { loop { return match handler.handlemut(&mut pingpong).await { Ok(HandlerStatus::Active) => continue, otherwise => otherwise, }; } }, async { smol::Timer::after(std::time::Duration::fromsecs(60)).await; client.disconnect().await.unwrap(); } ); assert!(n.isok()); assert!(h.isok()); }); ```

Tokio example:

```rust let options = ConnectOptions::new("TokioTcpPingPong".to_string());

let (mut network, mut handler, client) = new_tokio(options);

let stream = tokio::net::TcpStream::connect(("broker.emqx.io", 1883)) .await .unwrap();

network.connect(stream).await.unwrap();

client.subscribe("mqrstt").await.unwrap();

let mut pingpong = PingPong { client: client.clone(), };

let (n, h, ) = tokio::join!( async { loop { return match network.run().await { Ok(NetworkStatus::Active) => continue, otherwise => otherwise, }; } }, async { loop { return match handler.handlemut(&mut pingpong).await { Ok(HandlerStatus::Active) => continue, otherwise => otherwise, }; } }, async { tokio::time::sleep(Duration::from_secs(60)).await; client.disconnect().await.unwrap(); } ); ```

Important notes:

License

Licensed under

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed under MPL-2.0, without any additional terms or conditions.