Skip to content

Commit

Permalink
Enhance SupportedEra implementation
Browse files Browse the repository at this point in the history
Use 'strum' macros to make the enum variant listable.
  • Loading branch information
jpraynaud committed Feb 17, 2023
1 parent 9664b9f commit 310eedc
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 49 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ sha2 = "0.10.2"
slog = { version = "2.7.0", features = ["max_level_trace", "release_max_level_debug"] }
slog-scope = "4.4.0"
sqlite = "0.28"
strum = "0.24.1"
strum_macros = "0.24.1"
thiserror = "1.0.31"
tokio = { version = "1.17.0", features = ["full"] }
walkdir = "2"
Expand Down
2 changes: 1 addition & 1 deletion mithril-common/src/era/adapters/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct BootstrapAdapter;
impl EraReaderAdapter for BootstrapAdapter {
async fn read(&self) -> Result<Vec<EraMarker>, Box<dyn std::error::Error + Sync + Send>> {
Ok(vec![EraMarker::new(
&SupportedEra::Thales.to_string(),
&SupportedEra::eras().first().unwrap().to_string(),
Some(Epoch(1)),
)])
}
Expand Down
69 changes: 21 additions & 48 deletions mithril-common/src/era/supported_era.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,48 @@
use std::str::FromStr;

use serde::Deserialize;
use thiserror::Error;
use strum::IntoEnumIterator;
use strum_macros::{Display, EnumIter, EnumString};

/// Error related to [SupportedEra] String parsing implementation.
pub type UnsupportedEraError = strum::ParseError;

/// The era that the software is running or will run
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[derive(Display, EnumString, EnumIter, Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[strum(serialize_all = "lowercase")]
pub enum SupportedEra {
/// Thales era
Thales,
}

impl SupportedEra {
/// Retrieve the list of supported eras
pub fn eras() -> Vec<Self> {
Self::iter().collect()
}

/// Retrieve a dummy era (for test only)
#[cfg(any(test, feature = "test_only"))]
pub fn dummy() -> Self {
Self::Thales
}
}

/// Error related to [SupportedEra] String parsing implementation.
#[derive(Error, Debug)]
#[error("Unable to transform era '{0}' into a currently supported era.")]
pub struct UnsupportedEraError(String);

impl FromStr for SupportedEra {
type Err = UnsupportedEraError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.trim().to_lowercase();

let era = match s.as_str() {
"thales" => Self::Thales,
_ => return Err(UnsupportedEraError(s)),
};

// This is intended to make the compiler to complain when a new variant
// is added in order not to forget to add a conversion for the new
// variant.
match era {
Self::Thales => Ok(Self::Thales),
}
}
}

impl ToString for SupportedEra {
fn to_string(&self) -> String {
match self {
Self::Thales => "thales".to_owned(),
}
Self::eras().first().unwrap().to_owned()
}
}

#[cfg(test)]
mod tests {
use super::*;

const ERA_NAME: &str = "thales";
use std::str::FromStr;

#[test]
fn from_str() {
let supported_era =
SupportedEra::from_str(ERA_NAME).expect("This era name should be supported.");
fn correct_number_of_eras() {
let total_eras = SupportedEra::eras().len();

assert_eq!(SupportedEra::dummy(), supported_era);
assert!(total_eras > 0);
assert!(total_eras <= 2);
}

#[test]
fn from_bad_str() {
let era_name = &format!(" {} ", ERA_NAME.to_ascii_uppercase());
let supported_era =
SupportedEra::from_str(era_name).expect("This era name should be supported.");
fn from_str() {
let supported_era = SupportedEra::from_str(&SupportedEra::dummy().to_string())
.expect("This era name should be supported.");

assert_eq!(SupportedEra::dummy(), supported_era);
}
Expand Down

0 comments on commit 310eedc

Please sign in to comment.