How to fix unused lifetime?

While trying to create a simple webserver in Rocket, I ran into the problem that I wanted to redirect or send html data, depending on certain conditions as follows:

#[post("/test/<some_string>")]
// This doesn't work Redirect and Html are different types.
pub fn test(some_string: String) -> _ {
    if validate(some_string) {
        Redirect("/dashboard")
    } else {
        content::Html("<h1>Hello World</h1>")
    }
}

This clearly doesn't work as Html and Redirect are clearly different types. Then I tried to create an enum with different responder types so I could use different responder types in the same function, this resulted in the following code:

pub enum TwoResponders<'r, T: Responder<'r>, V: Responder<'r>> {
    ResponderOne(T),
    ResponderTwo(V),
}

impl<'r, T: Responder<'r>, V: Responder<'r>> Responder<'r> for TwoResponders<'r, T, V> {
    fn respond_to(self, request: &Request) -> response::Result<'r> {
        match self {
            TwoResponders::ResponderOne(responder) => responder.respond_to(request),
            TwoResponders::ResponderTwo(responder) => responder.respond_to(request),
        }
    }
}

This however, didn't work either, because now the Rust compiler complains that the lifetime 'r is unused in the struct TwoResponders. I would think this is not the case as it is used in defining the traits T and V need to have, the Rust compiler thinks differently however, and it has the final word as always.

I was thinking of adding a PhantomData however that seemed like an incredibly ugly solution for something which shouldn't be this difficult to my knowledge.

Is there a better way to fix this?

Upvotes: 0

Views: 156

Answers (1)

Freyja
Freyja

Reputation: 40814

In cases like this, where the generic type bounds require some otherwise unused type parameter or lifetime and adding PhantomData makes things unnecessarily ugly, I find it cleanest to just remove the type bounds entirely from the type itself, and only keep them on the impl block:

pub enum TwoResponders<T, V> {
    ResponderOne(T),
    ResponderTwo(V),
}

impl<'r, T: Responder<'r>, V: Responder<'r>> Responder<'r> for TwoResponders<T, V> {
    fn respond_to(self, request: &Request) -> response::Result<'r> {
        match self {
            TwoResponders::ResponderOne(responder) => responder.respond_to(request),
            TwoResponders::ResponderTwo(responder) => responder.respond_to(request),
        }
    }
}

Upvotes: 3

Related Questions