IntoStaticStr but from immutable reference to an enum From<&MyEnum>
I need IntoStaticStr but from immutable reference to an enum From<&MyEnum> for &'static str on an &Enum is it possible to add?
Because without it the only way is to clone the enum to get the static string by using .into() .as_ref() doesn't work either because it doesn't return the 'static lifetime
Or am I just missing some rust construct that can easily achieve this?
use strum_macros::{AsRefStr, IntoStaticStr};
#[derive(AsRefStr, IntoStaticStr)]
enum MyEnum {
Foo,
}
fn main() {
let v = MyEnum::Foo;
let str2: &'static str = v.as_ref();
let str: &'static str = v.into();
drop(v);
}
error[E0597]: `v` does not live long enough
--> src/main.rs:9:30
|
8 | let v = MyEnum::Foo;
| - binding `v` declared here
9 | let str2: &'static str = v.as_ref();
| ------------ ^^^^^^^^^^ borrowed value does not live long enough
| |
| type annotation requires that `v` is borrowed for `'static`
...
12 | }
| - `v` dropped here while still borrowed
error[E0505]: cannot move out of `v` because it is borrowed
--> src/main.rs:10:29
|
8 | let v = MyEnum::Foo;
| - binding `v` declared here
9 | let str2: &'static str = v.as_ref();
| ------------ ---------- borrow of `v` occurs here
| |
| type annotation requires that `v` is borrowed for `'static`
10 | let str: &'static str = v.into();
| ^ move out of `v` occurs here
error[E0505]: cannot move out of `v` because it is borrowed
--> src/main.rs:11:10
|
8 | let v = MyEnum::Foo;
| - binding `v` declared here
9 | let str2: &'static str = v.as_ref();
| ------------ ---------- borrow of `v` occurs here
| |
| type annotation requires that `v` is borrowed for `'static`
10 | let str: &'static str = v.into();
11 | drop(v);
| ^ move out of `v` occurs here
error[E0382]: use of moved value: `v`
--> src/main.rs:11:10
|
8 | let v = MyEnum::Foo;
| - move occurs because `v` has type `MyEnum`, which does not implement the `Copy` trait
9 | let str2: &'static str = v.as_ref();
10 | let str: &'static str = v.into();
| ------ `v` moved due to this method call
11 | drop(v);
| ^ value used here after move
|
note: `into` takes ownership of the receiver `self`, which moves `v`
--> /home/lajos/snap/rustup/common/rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:448:13
|
448 | fn into(self) -> T;
| ^^^^
Some errors have detailed explanations: E0382, E0505, E0597.
For more information about an error, try `rustc --explain E0382`.
#131 AsStr would solve it https://github.com/Peternator7/strum/issues/131#issuecomment-1286851891
maybe also duplicate of #152 ?
Aww, it actually works with the depracated feature. Can you undeprecate it? or maybe just rename to as_str as suggested in https://github.com/Peternator7/strum/issues/131#issuecomment-1286851891 ?
use strum::{AsStaticRef, AsStaticStr};
#[derive(AsStaticStr)]
enum MyEnum {
Foo,
}
fn main() {
let v = MyEnum::Foo;
let str3: &'static str = v.as_static();
println!("{}", str3);
drop(v);
}
How about AsStaticRef<str> -> AsStr and AsStaticStr -> AsStr
pub trait AsStr{
fn as_str(&self) -> &'static str
}
Plus also if the From<&MyEnum> is possible for IntoStaticStr
This should already work, but you might need to play with the de-refs to get rustc to pick the right impl. Check out this test for an example
you are correct, it works.
So I turn this into a question. I don't know how to declare Into<&'static str> trait so it works for both Enum and &Enum. Whereas with AsStaticStr it works. Here is the code I want to make work.
What trait should be added to EnumIntoStaticStr so it compiles?
use strum::{AsStaticRef, AsStaticStr, IntoStaticStr};
trait EnumIntoStaticStr: Into<&'static str> {}
impl<T: Into<&'static str>> EnumIntoStaticStr for T {}
trait EnumAsStaticStr: AsStaticRef<str> {}
impl<T: AsStaticRef<str>> EnumAsStaticStr for T {}
#[derive(AsStaticStr)]
enum MyEnum {
Foo,
Bar(String),
}
#[derive(IntoStaticStr)]
enum MyEnum2 {
Foo2,
Bar(String),
}
fn main() {
let v = MyEnum::Foo;
let str = borrow_as_str(&v);
drop(v);
println!("{}", str);
let v2 = MyEnum2::Foo2;
let str2 = borrow_into_str(&v2);
drop(v2);
println!("{}", str2);
}
fn move_as_str(v: impl EnumAsStaticStr) -> &'static str {
v.as_static()
}
fn borrow_as_str(v: &impl EnumAsStaticStr) -> &'static str {
v.as_static()
}
fn move_into_str(v: impl EnumIntoStaticStr) -> &'static str {
v.into()
}
fn borrow_into_str(v: &impl EnumIntoStaticStr) -> &'static str {
v.into()
}
Error:
error[E0277]: the trait bound `&str: From<&impl EnumIntoStaticStr>` is not satisfied
--> src/main.rs:45:7
|
45 | v.into()
| ^^^^ the trait `From<&impl EnumIntoStaticStr>` is not implemented for `&str`
|
= note: required for `&impl EnumIntoStaticStr` to implement `Into<&str>`
help: consider dereferencing here
|
45 | (*v).into()
| ++ +
For more information about this error, try `rustc --explain E0277`.```
I got my answer on stackoverflow https://stackoverflow.com/questions/77120723/how-to-declare-supertraits-intot-so-it-works-with-both-move-and-borrow/77122298#77122298
I would vouch for keeping AsStaticStr because there is a difference from IntoStaticStr as shown in previous comment.
Apart from that this issue can be closed from my side