-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add impl TryFrom<T> for E where E is a C-like #[repr(T)] enum #2783
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This was easy enough: macro_rules! enum_try_from_int {
(
#[repr($T: ident)]
$( #[$meta: meta] )*
$vis: vis enum $Name: ident {
$(
$Variant: ident = $value: expr
),*
$( , )?
}
) => {
#[repr($T)]
$( #[$meta] )*
$vis enum $Name {
$(
$Variant = $value
),*
}
impl std::convert::TryFrom<$T> for $Name {
type Error = ();
fn try_from(value: $T) -> Result<$Name, ()> {
match value {
$(
$value => Ok($Name::$Variant),
)*
_ => Err(())
}
}
}
}
}
enum_try_from_int! {
#[repr(u32)]
#[derive(PartialEq)]
pub enum Foo {
Bar = 4,
Baz = 7,
}
}
pub fn main() {
use std::convert::TryFrom;
assert!(Foo::try_from(7).unwrap() == Foo::Baz)
} But yeah it would be nicer as a derive proc macro. It’s debatable whether this should be in the standard library rather than crates.io, but I personally wouldn’t be opposed. |
I personally think (as a general principle) that whatever crate provides the trait should also provide the derive macro (well, they cannot be the same crate exactly, but the same project) if a reasonable implementation can be given. In the case of the standard library it would be the language that should provide said derives when structural impls can be given. |
If I make a PR for this is it likely to get merged? |
It's probably a large enough addition to the language to be RFC-worthy. I think we should also consider adding derives more holistically rather than a one-off. |
I don't know the details of proc macros that well, will the derive always see the |
@Centril Why does adding a simple Trait to an object require an entire RFC? |
Well it's adding a general mechanism for deriving, not one specific object, and it is a language change that needs some design work so an RFC seems appropriate. |
Doesn’t the |
I think I phrased that poorly... Maybe "general" was too general here. I really meant specifically adding @canndrew Let's check the mood? cc @rust-lang/lang. @bluss I believe that if |
|
Although this does have some issues with letting users specify the error-result manually (but we could just restrict it to enums). And I think the intrinsic needed to do this are unstable? Shouldn't affect the stdlib tho. |
I think it’s find for this conversion to always have the same What intrinsic do you mean? |
My bad, I mistook the intrinsic that got the discriminant of an non-C enum. Is there an intrinsic for an int to a C-enum already implemented like the one proposed in the internals thread? |
Why would this need an intrinsic to convert from an int to an enum? The derive can just match. |
Yes, there is And even without unsafe code, a |
My two cents: I can't quite tell what is being proposed here -- however I have long wanted some form of macro like this to handle "C-like" enums. It seems like the behavior of It seems like we have plenty of precedent for shipping derives with the language -- most of the standard traits ship them -- so I'm not concerned about shipping one for As far as procs, this ultimately strikes me as more of a "libs team" call than a lang team one, since we're not adding some fundamental new mechanism, as far as I can tell? Just employing the existing one. I think the libs team process there tends to not require RFCs per se? |
I've certainly seen people ask often how to do this in chat, so it does seem like a plausible place to do something. On the other hand, just So overall I wonder if it's better to just leave this kind of thing to https://docs.rs/enum_derive/0.1.7/enum_derive/ and friends... |
This is a very common problem. People keep reinventing crates for this, and most crates settle on an interface that is identical or very close to what is proposed here.
|
FWIW, as one of the maintainers of num_enum, I'd be happy to donate it or any parts of it into |
Hello, what is the state of it? |
This is a problem that has come up a lot. The most recent discussion I could find about it is the internals thread here, but that thread has been locked and I figured this should probably have an "official" issue somewhere.
There's currently no (good) way to convert from an enum integer discriminant value to the enum itself. Enums should support deriving
TryFrom
for this purpose. eg.The text was updated successfully, but these errors were encountered: