{"action":"created","issue":{"url":"https://api.github.com/repos/danburkert/prost/issues/76","repository_url":"https://api.github.com/repos/danburkert/prost","labels_url":"https://api.github.com/repos/danburkert/prost/issues/76/labels{/name}","comments_url":"https://api.github.com/repos/danburkert/prost/issues/76/comments","events_url":"https://api.github.com/repos/danburkert/prost/issues/76/events","html_url":"https://github.com/danburkert/prost/issues/76","id":297235756,"node_id":"MDU6SXNzdWUyOTcyMzU3NTY=","number":76,"title":"Suggestion for enumerations","user":{"login":"vorner","id":11783500,"node_id":"MDQ6VXNlcjExNzgzNTAw","avatar_url":"https://avatars2.githubusercontent.com/u/11783500?v=4","gravatar_id":"","url":"https://api.github.com/users/vorner","html_url":"https://github.com/vorner","followers_url":"https://api.github.com/users/vorner/followers","following_url":"https://api.github.com/users/vorner/following{/other_user}","gists_url":"https://api.github.com/users/vorner/gists{/gist_id}","starred_url":"https://api.github.com/users/vorner/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vorner/subscriptions","organizations_url":"https://api.github.com/users/vorner/orgs","repos_url":"https://api.github.com/users/vorner/repos","events_url":"https://api.github.com/users/vorner/events{/privacy}","received_events_url":"https://api.github.com/users/vorner/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":14,"created_at":"2018-02-14T20:33:21Z","updated_at":"2018-06-14T22:11:05Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"Hello\r\n\r\nI'm still a bit unhappy about the fact enumerations are i32 values, for two reasons:\r\n\r\n* Handling them is cumbersome. I can't just access the field, I have to convert it first…\r\n* They are interchangeable. Let's say I have enums `enum Direction { Unspecified = 0, In = 1, Out = 2 }` and `enum Proto { Unspecified = 0, Udp = 1, Tcp = 2 }`. I can do `message.proto = Direction::Out as i32` and it will work. I can do `Direction::from_i32(message.proto)` and it'll work. And I like Rust's strict type system keeping an eye on me.\r\n\r\nSo I was wondering if there could be more convenient and safer alternative. What about:\r\n\r\n* Create the enum as it is now, eg `enum Direction { Unspecified = 0, In = 1, Out = 2 }`\r\n* Also create a companion `struct DirectionRaw(pub i32)`\r\n\r\nThis way, we can have conversion methods on both of them to each other, but not with i32 directly (type safety). The fact the conversion methods would be on the `DirectionRaw` would make it more discoverable.\r\n\r\nFurthermore, I think the conversion method would be something like `fn enum(&self) -> Option<Direction>` ‒ this way it is possible to both know if the input was valid/known and call `unwrap_or_default()` on it to get the appropriate default.\r\n\r\nDoes that make sense? Or does it have some downsides I don't see?\r\n\r\nI would be willing to implement it, but I wanted to check first if it makes sense."},"comment":{"url":"https://api.github.com/repos/danburkert/prost/issues/comments/397454037","html_url":"https://github.com/danburkert/prost/issues/76#issuecomment-397454037","issue_url":"https://api.github.com/repos/danburkert/prost/issues/76","id":397454037,"node_id":"MDEyOklzc3VlQ29tbWVudDM5NzQ1NDAzNw==","user":{"login":"brain0","id":1160158,"node_id":"MDQ6VXNlcjExNjAxNTg=","avatar_url":"https://avatars1.githubusercontent.com/u/1160158?v=4","gravatar_id":"","url":"https://api.github.com/users/brain0","html_url":"https://github.com/brain0","followers_url":"https://api.github.com/users/brain0/followers","following_url":"https://api.github.com/users/brain0/following{/other_user}","gists_url":"https://api.github.com/users/brain0/gists{/gist_id}","starred_url":"https://api.github.com/users/brain0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brain0/subscriptions","organizations_url":"https://api.github.com/users/brain0/orgs","repos_url":"https://api.github.com/users/brain0/repos","events_url":"https://api.github.com/users/brain0/events{/privacy}","received_events_url":"https://api.github.com/users/brain0/received_events","type":"User","site_admin":false},"created_at":"2018-06-14T22:11:05Z","updated_at":"2018-06-14T22:11:05Z","author_association":"NONE","body":"I am aware of that, and from what I can see in the comment, you can either get the i32, or you can get the enum, but in the latter case, you simply fall back to the default if it is out of range. I don't see a way to easily determine that the value was out of range, other than comparing the i32 value against known values manually. The version I just proposed is more obvious and allows to explicitly distinguish between the case of a valid enum value and an unknown one, without losing any information.\r\n\r\nAccessing the enum field via `match` or `if let` expressions to determine whether the enum value was in range feels natural in Rust code. At least to me, having two ways to access the same value, both giving me incomplete information in the worst case, does not feel natural at all. In other places, prost generated code has an elegance that other protobuf implementations lack (have you seen protobuf generated C++ code?), but the enums feel wrong."}}
{"actor":{"display_login":"brain0"}}