Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to implement tokio_util::codec::{Decoder, Encoder} with mqttrs version 0.4 #45

Open
svanharmelen opened this issue Sep 29, 2021 · 4 comments

Comments

@svanharmelen
Copy link

I updated our app to use tokio 1.x the other day, and with that I also updated mqttrs from 0.3 to 0.4. But since Packet now requires a lifetime, I don't see how I can implement tokio_util::codec::{Decoder, Encoder} using this version.

I tried the following code:

use bytes::BytesMut;
use mqttrs::{Error, Packet};
use tokio_util::codec::{Decoder, Encoder};

pub struct MQTTCodec;

impl MQTTCodec {
   pub fn new() -> MQTTCodec {
       MQTTCodec {}
   }
}

impl<'a> Decoder for MQTTCodec {
   type Item<'a> = Packet<'a>;
   type Error = Error;

   fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Packet<'a>>, Self::Error> {
       mqttrs::decode_slice(src)
   }
}

impl Encoder<Packet<'_>> for MQTTCodec {
   type Error = Error;

   fn encode(&mut self, packet: Packet, buf: &mut BytesMut) -> Result<(), Self::Error> {
       mqttrs::encode_slice(&packet, &mut buf)
   }
}

But this gives me:

error[E0658]: generic associated types are unstable
  --> iot-gateway/tests/mqttbroker/codec.rs:14:5
   |
14 |     type Item<'a> = Packet<'a>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information

error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
  --> iot-gateway/tests/mqttbroker/codec.rs:14:15
   |
13 | impl<'a> Decoder for MQTTCodec {
   |      -- first declared here
14 |     type Item<'a> = Packet<'a>;
   |               ^^ lifetime `'a` already in scope

Do you have any suggestions or pointers on how to make this work again with mqttrs 0.4? Thanks!

@svanharmelen
Copy link
Author

@00imvj00 any ideas, pointers or suggestions? Thanks!

@00imvj00
Copy link
Owner

00imvj00 commented Oct 6, 2021

@svanharmelen apologies for the delayed reply. This is a known issue. @MathiasKoch has integrated this with async, he might be able to help more. I hope. @MathiasKoch any ideas???

@MathiasKoch
Copy link
Contributor

I have not used in any async code at all. All my applications are #![no_std]

I am however currently running with a fork of this, as i am doing some other no-std, no-alloc optimizations for my application, so feel free to disregard me currently. I do hope we can patch stuff together eventually, for a good community mqtt encoder crate that can be used across the entire ecosystem.
If you want to solve this without reverting to std only, i would look into the Managed crate, and how they use it in smoltcp.
smoltcp does no_std, no_alloc with full async support and no rough edges on neither std users, nor no_std.

@stabler
Copy link

stabler commented Dec 11, 2021

I recently tried to update mqtt-async-client-rs and ran into the same issue. The reference on Packet makes it very difficult to integrate into applications which process incoming packets in a separate context- especially given the limited tooling to make a copy of the underlying data.

Now that it's been a few months, how are people approaching this? Are there examples of integrations that I could look at?

If I could propose a solution that uses Packet<'a> by default but allows conversion to owned objects for applications that require it, what about something like this:

pub enum Packet<'a> {
  Connect(Connect<'a>),
  Connack(Connack),
  ...
}

pub enum PacketOwned {
  Connect(ConnectOwned),
  Connack(Connack),
  ...
}

impl<'a> Packet<'a> {
  pub fn to_owned(&'a self) -> PacketOwned {
    ...
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants