From d315f583cafc8462aefd3056f371a60004bebb3b Mon Sep 17 00:00:00 2001
From: Georgy Moshkin <gmoshkin@picodata.io>
Date: Thu, 6 Oct 2022 09:05:49 +0300
Subject: [PATCH] refactor: Grade and TargetGrade using define_str_enum!

---
 src/traft/failover.rs |  2 +-
 src/traft/mod.rs      | 78 +++++++++++++++++--------------------------
 2 files changed, 31 insertions(+), 49 deletions(-)

diff --git a/src/traft/failover.rs b/src/traft/failover.rs
index 9d9671b49f..6bd719f344 100644
--- a/src/traft/failover.rs
+++ b/src/traft/failover.rs
@@ -115,7 +115,7 @@ fn raft_update_peer(
         super::PeerChange::Grade(grade) => {
             tlog!(Warning, "attempt to change grade by peer";
                 "instance_id" => instance_id,
-                "grade" => grade.to_str(),
+                "grade" => grade.as_str(),
             );
             false
         }
diff --git a/src/traft/mod.rs b/src/traft/mod.rs
index 2fb0f117cd..2f3350e9ea 100644
--- a/src/traft/mod.rs
+++ b/src/traft/mod.rs
@@ -23,7 +23,7 @@ use serde::{Deserialize, Serialize};
 use std::any::Any;
 use std::collections::HashMap;
 use std::convert::TryFrom;
-use std::fmt::{Debug, Display};
+use std::fmt::Debug;
 use std::time::Duration;
 use uuid::Uuid;
 
@@ -834,35 +834,24 @@ pub struct SyncRaftResponse {
 impl Encode for SyncRaftResponse {}
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Activity state of an instance.
-#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
-pub enum Grade {
-    // Instance has gracefully shut down or has not been started yet.
-    Offline,
-    // Instance has synced by commit index.
-    RaftSynced,
-    // Instance is active and is handling requests.
-    Online,
-    // Instance has permanently removed from cluster.
-    Expelled,
-}
-
-impl Grade {
-    const fn to_str(&self) -> &str {
-        match self {
-            Self::Offline => "Offline",
-            Self::RaftSynced => "RaftSynced",
-            Self::Online => "Online",
-            Self::Expelled => "Expelled",
-        }
+crate::define_str_enum! {
+    /// Activity state of an instance.
+    pub enum Grade {
+        // Instance has gracefully shut down or has not been started yet.
+        Offline = "Offline",
+        // Instance has synced by commit index.
+        RaftSynced = "RaftSynced",
+        // Instance is active and is handling requests.
+        Online = "Online",
+        // Instance has permanently removed from cluster.
+        Expelled = "Expelled",
     }
+    FromStr::Err = UnknownGrade;
 }
 
-impl Display for Grade {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.write_str(self.to_str())
-    }
-}
+#[derive(thiserror::Error, Debug)]
+#[error("unknown grade {0:?}")]
+pub struct UnknownGrade(pub String);
 
 impl Default for Grade {
     fn default() -> Self {
@@ -870,29 +859,22 @@ impl Default for Grade {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)]
-pub enum TargetGrade {
-    // Instance should be configured up
-    Online,
-    // Instance should be gracefully shut down
-    Offline,
-    // Instance should be removed from cluster
-    Expelled,
-}
-impl TargetGrade {
-    const fn to_str(&self) -> &str {
-        match self {
-            Self::Online => "Online",
-            Self::Offline => "Offline",
-            Self::Expelled => "Expelled",
-        }
-    }
-}
-impl Display for TargetGrade {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        f.write_str(self.to_str())
+crate::define_str_enum! {
+    pub enum TargetGrade {
+        // Instance should be configured up
+        Online = "Online",
+        // Instance should be gracefully shut down
+        Offline = "Offline",
+        // Instance should be removed from cluster
+        Expelled = "Expelled",
     }
+    FromStr::Err = UnknownTargetGrade;
 }
+
+#[derive(thiserror::Error, Debug)]
+#[error("unknown target grade {0:?}")]
+pub struct UnknownTargetGrade(pub String);
+
 impl Default for TargetGrade {
     fn default() -> Self {
         Self::Online
-- 
GitLab