Repository: tokio-rs/prost (language: rust)

Issue:
Hash, Ord and PartialOrd for enums
Hello

The generated enum types that are generated for protobuffer enums don't implement `Hash`, `PartialOrd` nor `Ord`. As these are simple enums (without data inside their variants), there doesn't seem to be a reason for that (or maybe I just don't see it).

It would be handy to be able to use them as part of keys in hash maps or btree maps, which this makes harder. I guess I could use their numeric representation, but in case I already went through, validated the message and keep only extracted data (as the enums, for easier manipulation in Rust), this makes it harder.

Would it be OK to add them? Should I try doing it?


Discussion / hints:
This is a good idea.  I'm going to work on this, I think it should be very straightforward.

Fix patch:
diff --git a/prost-build/src/code_generator.rs b/prost-build/src/code_generator.rs
index 4b43af2f8..323427946 100644
--- a/prost-build/src/code_generator.rs
+++ b/prost-build/src/code_generator.rs
@@ -461,7 +461,7 @@ impl <'a> CodeGenerator<'a> {
 
         self.append_doc();
         self.push_indent();
-        self.buf.push_str("#[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]\n");
+        self.buf.push_str("#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]\n");
         self.append_type_attributes(&fq_enum_name);
         self.push_indent();
         self.buf.push_str("pub enum ");
diff --git a/prost-types/src/protobuf.rs b/prost-types/src/protobuf.rs
index 67cf57273..60182a688 100644
--- a/prost-types/src/protobuf.rs
+++ b/prost-types/src/protobuf.rs
@@ -146,7 +146,7 @@ pub struct FieldDescriptorProto {
     pub options: ::std::option::Option<FieldOptions>,
 }
 pub mod field_descriptor_proto {
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum Type {
         /// 0 is reserved for errors.
         /// Order is weird for historical reasons.
@@ -181,7 +181,7 @@ pub mod field_descriptor_proto {
         /// Uses ZigZag encoding.
         Sint64 = 18,
     }
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum Label {
         /// 0 is reserved for errors
         Optional = 1,
@@ -405,7 +405,7 @@ pub struct FileOptions {
 }
 pub mod file_options {
     /// Generated classes can be optimized for speed or code size.
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum OptimizeMode {
         /// Generate complete code for parsing, serialization,
         Speed = 1,
@@ -549,14 +549,14 @@ pub struct FieldOptions {
     pub uninterpreted_option: ::std::vec::Vec<UninterpretedOption>,
 }
 pub mod field_options {
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum CType {
         /// Default mode.
         String = 0,
         Cord = 1,
         StringPiece = 2,
     }
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum JsType {
         /// Use the default type.
         JsNormal = 0,
@@ -640,7 +640,7 @@ pub mod method_options {
     /// Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
     /// or neither? HTTP based RPC implementation may choose GET verb for safe
     /// methods, and PUT verb for idempotent methods instead of the default POST.
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum IdempotencyLevel {
         IdempotencyUnknown = 0,
         /// implies idempotent
@@ -1041,7 +1041,7 @@ pub struct Field {
 }
 pub mod field {
     /// Basic field types.
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum Kind {
         /// Field type unknown.
         TypeUnknown = 0,
@@ -1083,7 +1083,7 @@ pub mod field {
         TypeSint64 = 18,
     }
     /// Whether a field is optional, required, or repeated.
-    #[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
     pub enum Cardinality {
         /// For fields with unknown cardinality.
         Unknown = 0,
@@ -1145,7 +1145,7 @@ pub struct Option {
     pub value: ::std::option::Option<Any>,
 }
 /// The syntax in which a protocol buffer element is defined.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
 pub enum Syntax {
     /// Syntax `proto2`.
     Proto2 = 0,
@@ -1672,7 +1672,7 @@ pub struct ListValue {
 /// `Value` type union.
 ///
 ///  The JSON representation for `NullValue` is JSON `null`.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Enumeration)]
 pub enum NullValue {
     /// Null value.
     NullValue = 0,


Test patch: