Circumventing a selfless trait

Say there is a struct of type foo<T: bar> that I want to use in my own structs from a foreign crate.

The trait bar is defined as such:

pub trait bar {
    fn type() -> &'static str;
}

This definition basically mandates the use of an impl of the form:

struct baz;
impl bar for baz {
    fn type() -> &'static str { 
        "static string here"
    }
}

So far, the only possible way to make this work I could think of would be to have lazy_static!'d strings I can write to from my string deduction function, but I would rather not have mutex unsafe global soup (and having already tried this, I don't think I can even make that work, I'll need drop types in static).

Is there a more Rustic way to obey this trait bound but still return runtime deduced strings? The absence of self in the trait methods makes me think I'm stuck. I'm just looking for some way to construct this type and obey this trait while providing strings somewhere for this function to return.

You could use the leak crate, which can convert String to &'static str. As the name suggests, the memory will be leaked and won't be reclaimable until the process exits, so you'll probably want to at least cache it somewhere.

1 Like

Leak does work! Naturally, having to write...

unsafe { 
     auth_uri = config.authorization_endpoint.clone().into_string().leak(); 
}

Is a bit ugly, and very unidiomatic, but it does get the job done. Thank you!

Still wondering if there is a magical way to make this all not feel like a terrible hack.

Can you file a bug report against that crate? :slight_smile: A Cow<'static, str> would be more appropriate if they don't want to deal with arbitrary lifetimes. Do you happen to know why they require a static string?

How dynamic are the strings you want? Could you maybe codegen them at compile time into literals?

1 Like

I did file a bug against the crate, but do want this working in the in meantime. The leak strategy seems like an alright stopgap.

They aren't returning Cows because right now there is simply no way to get a dynamic runtime string in the trait fn impl body without a self reference. Implementation wise, this struct is being used as a way to get polymorphic urls per API target without having to provide them as a contiguous object (the actual structs that parameterize them hold them as PhantomData).

I'm getting these strings from a json response object, so they are pretty much as dynamic as they can get. No way to deduce them in macros until after a full round trip.