I need to have methods that can take &str, std::string::String and my own string type, rust_fb::string::String. Previously I was able to get AsRef<str> parameters, however I wasn't able to directly pass my own string type to my functions, which end up with a special method to convert my string type to std::string::String and finally to &str. This is what the problem looks like:
use rust_fb::string::String;
fn f<S: AsRef<str>>(_s: S) {
}
f(my_own_string_type.to_std_string().as_ref());
In reality, there'll be methods like concat, which should be able to receive any of the above string types.
Implementing AsRef in different ways just doesn't work. For example, instead of a function taking AsRef<str>, I could write a function taking AsRef<rust_fb::string::String>, but the problem is... lifetime.
Just to advice I can't dereference to &str because that'd make available methods that return &str (e.g., slicing returns &str) or that use Rust's existing regex support. Furthermore, my string type doesn't store any kind of std::string::String or Box<str>, it's a bit Python-based, thus it uses either latin-1, UCS-2 or UCS-4 in representation.
Unfortunately I can't expose API using &str, because many of its methods return &str, and I also want to implement methods using my own regular expression implementation.
temporary value created here
rustc E0515
string.rs(522, 9): original diagnostic
cannot return reference to temporary value
returns a reference to data owned by the current function
rustc E0515
string.rs(522, 10): temporary value created here
Is it impossible to achieve what I want? I want to directly receive my custom string type, and implicitly convert &str and &std::string::String to it with AsRef<rust_fb::string::String>.
Whatever you want to borrow has to live somewhere already (returning a reference to a temporary would cause a dangling reference). So if your own type doesn't contain a T, then you can't1 return a &T.
1: of course, there are ways to technucally do that, e.g. always returning the same reference to a static, or leaking memory and returning a reference to a leaked heap-allocated value. But those are not reasonably what you want.
I'd say the typical approaches in this situation (excluding AsRef which you can't use here) are
Implement conversions (using From) from String and &str to rust_fb::string::String and take s: impl Into<rust_fb::string::String>. Then inside the function you can immediately convert the argument into your own string type and work with it from there.
Create a trait that has functions for the operations that you want to do and implement the trait for all three. You could either make concat generic, or even make concat a method for this custom trait.
Any AsRef<Something> based approach is generally not going to work if the types you want to use don't all contain a Something.