[Solved] Implement trait for struct with associated type

#1

Hello!
I want to implement a trait:

pub trait Decoder {
    type Item;
    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error>;
}

implementation:

pub(crate) struct Codec<'a>;

impl<'a> Decoder for Codec<'a> {
    type Item = Command<'a>;
    type Error = Error;

    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        unimplemented!()
    }
}
pub enum Command<'a> {
    Info(Info<'a>),
}
   |
41 | pub(crate) struct Codec<'a>;
   |                         ^^ unused type parameter
   |
   = help: consider removing `'a` or using a marker such as `std::marker::PhantomData`

what i can do here?

#2

You can use PhantomData to embed a otherwise unused lifetime in a struct.

use std::marker::PhantomData;

struct Codec<'a>{
  _marker: PhantomData(&'a bool),
}

impl<'a> Codec<'a> {
  fn new() -> Self {
    Self{
      _marker: PhantomData,
    }
  }
}
#3

thank you very much!

#4

Given your usage, I doubt you will manage to actually implement what you want with a PhantomData:

you want the returned Self::Item to be borrowing from something, most probably from Self (or it could be borrowing from BytesMut instead).

This gives:

pub
trait Decoder<'a> /* <- put the parameter here */ {
    type Item; // may depend on `'a`
    fn decode (
        self: &'a mut Self, // 'a is the lifetime of a borrow of Self
        src: &'_ mut BytesMut,
    ) -> Result<
        Option<Self::Item>,
        Self::Error,
    >;
}

or if the borrow comes from BytesMut:

pub
trait Decoder<'a> /* <- put the parameter here */ {
    type Item; // may depend on `'a`
    fn decode (
        self: &'_ mut Self,
        src: &'a mut BytesMut, // 'a is the lifetime of a borrow of BytesMut
    ) -> Result<
        Option<Self::Item>,
        Self::Error,
    >;
}

In which case I recommend renaming 'a for readability:

pub
trait Decoder<'bytes_mut> /* <- put the parameter here */ {
    type Item; // may depend on `'bytes_mut`
    fn decode (
        self: &'_ mut Self,
        src: &'bytes_mut mut BytesMut, // 'a is the lifetime of a borrow of BytesMut
    ) -> Result<
        Option<Self::Item>,
        Self::Error,
    >;
}
pub(crate)
struct Codec {
  // ...
}

impl<'a> Decoder<'a> for Codec {
    type Item = Command<'a>;
    type Error = Error;

    fn decode (
        self: &'a mut Self,
        src: &'_ mut BytesMut,
    ) -> Result<
        Option<Self::Item>,
        Self::Error,
    > {
        unimplemented!()
    }
}