Skip to content

Commit 40f0677

Browse files
committed
refactor(common): move parsing of EpochSpecifier from Epoch to self
The idea was to avoid import of `EpochSpecifier` in callers but since the import is needed anyway to match the result it's more clear for it to be part of the specifier api.
1 parent 175c434 commit 40f0677

File tree

3 files changed

+48
-38
lines changed

3 files changed

+48
-38
lines changed

mithril-aggregator/src/http_server/parameters.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub async fn expand_epoch(
6060
epoch_service: EpochServiceWrapper,
6161
) -> StdResult<ExpandedEpoch> {
6262
let epoch_str = epoch_str.to_lowercase();
63-
match Epoch::parse_specifier(&epoch_str)? {
63+
match EpochSpecifier::parse(&epoch_str)? {
6464
EpochSpecifier::Number(epoch) => Ok(ExpandedEpoch::Parsed(epoch)),
6565
EpochSpecifier::Latest => epoch_service
6666
.read()

mithril-client-cli/src/commands/cardano_db/list.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl CardanoDbListCommand {
8383
let cdb_v2_client = client.cardano_database_v2();
8484
let items = match &self.epoch {
8585
None => cdb_v2_client.list().await?,
86-
Some(epoch_str) => match Epoch::parse_specifier(epoch_str)? {
86+
Some(epoch_str) => match EpochSpecifier::parse(epoch_str)? {
8787
EpochSpecifier::Number(epoch) => cdb_v2_client.list_by_epoch(epoch).await?,
8888
EpochSpecifier::Latest => cdb_v2_client.list_for_latest_epoch().await?,
8989
EpochSpecifier::LatestMinusOffset(offset) => {

mithril-common/src/entities/epoch.rs

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use anyhow::Context;
77
use serde::{Deserialize, Serialize};
88
use thiserror::Error;
99

10-
use crate::StdResult;
1110
use crate::entities::arithmetic_operation_wrapper::{
1211
impl_add_to_wrapper, impl_partial_eq_to_wrapper, impl_sub_to_wrapper,
1312
};
13+
use crate::{StdError, StdResult};
1414

1515
const INVALID_EPOCH_SPECIFIER_ERROR: &str =
1616
"Invalid epoch: expected 'X', 'latest' or 'latest-X' where X is a positive 64-bit integer";
@@ -106,32 +106,6 @@ impl Epoch {
106106
pub fn has_gap_with(&self, other: &Epoch) -> bool {
107107
self.0.abs_diff(other.0) > 1
108108
}
109-
110-
/// Parses the given epoch string into an `EpochSpecifier`.
111-
///
112-
/// Accepted values are:
113-
/// - a `u64` number
114-
/// - `latest`
115-
/// - `latest-{offset}` where `{offset}` is a `u64` number
116-
pub fn parse_specifier(epoch_str: &str) -> StdResult<EpochSpecifier> {
117-
if epoch_str == "latest" {
118-
Ok(EpochSpecifier::Latest)
119-
} else if let Some(offset_str) = epoch_str.strip_prefix("latest-") {
120-
if offset_str.is_empty() {
121-
anyhow::bail!("Invalid epoch '{epoch_str}': offset cannot be empty");
122-
}
123-
let offset = offset_str.parse::<u64>().with_context(|| {
124-
format!("Invalid epoch '{epoch_str}': offset must be a positive 64-bit integer")
125-
})?;
126-
127-
Ok(EpochSpecifier::LatestMinusOffset(offset))
128-
} else {
129-
epoch_str
130-
.parse::<Epoch>()
131-
.map(EpochSpecifier::Number)
132-
.with_context(|| INVALID_EPOCH_SPECIFIER_ERROR)
133-
}
134-
}
135109
}
136110

137111
impl Deref for Epoch {
@@ -209,6 +183,42 @@ pub enum EpochSpecifier {
209183
LatestMinusOffset(u64),
210184
}
211185

186+
impl EpochSpecifier {
187+
/// Parses the given epoch string into an `EpochSpecifier`.
188+
///
189+
/// Accepted values are:
190+
/// - a `u64` number
191+
/// - `latest`
192+
/// - `latest-{offset}` where `{offset}` is a `u64` number
193+
pub fn parse(epoch_str: &str) -> StdResult<Self> {
194+
Self::from_str(epoch_str)
195+
}
196+
}
197+
198+
impl FromStr for EpochSpecifier {
199+
type Err = StdError;
200+
201+
fn from_str(epoch_str: &str) -> Result<Self, Self::Err> {
202+
if epoch_str == "latest" {
203+
Ok(EpochSpecifier::Latest)
204+
} else if let Some(offset_str) = epoch_str.strip_prefix("latest-") {
205+
if offset_str.is_empty() {
206+
anyhow::bail!("Invalid epoch '{epoch_str}': offset cannot be empty");
207+
}
208+
let offset = offset_str.parse::<u64>().with_context(|| {
209+
format!("Invalid epoch '{epoch_str}': offset must be a positive 64-bit integer")
210+
})?;
211+
212+
Ok(EpochSpecifier::LatestMinusOffset(offset))
213+
} else {
214+
epoch_str
215+
.parse::<Epoch>()
216+
.map(EpochSpecifier::Number)
217+
.with_context(|| INVALID_EPOCH_SPECIFIER_ERROR)
218+
}
219+
}
220+
}
221+
212222
impl Display for EpochSpecifier {
213223
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
214224
match self {
@@ -372,46 +382,46 @@ mod tests {
372382

373383
#[test]
374384
fn parse_epoch_number() {
375-
let parsed_value = Epoch::parse_specifier("5").unwrap();
385+
let parsed_value = EpochSpecifier::parse("5").unwrap();
376386
assert_eq!(EpochSpecifier::Number(Epoch(5)), parsed_value);
377387
}
378388

379389
#[test]
380390
fn parse_latest_epoch() {
381-
let parsed_value = Epoch::parse_specifier("latest").unwrap();
391+
let parsed_value = EpochSpecifier::parse("latest").unwrap();
382392
assert_eq!(EpochSpecifier::Latest, parsed_value);
383393
}
384394

385395
#[test]
386396
fn parse_latest_epoch_with_offset() {
387-
let parsed_value = Epoch::parse_specifier("latest-43").unwrap();
397+
let parsed_value = EpochSpecifier::parse("latest-43").unwrap();
388398
assert_eq!(EpochSpecifier::LatestMinusOffset(43), parsed_value);
389399
}
390400

391401
#[test]
392402
fn parse_invalid_str_yield_error() {
393-
let error = Epoch::parse_specifier("invalid_string").unwrap_err();
403+
let error = EpochSpecifier::parse("invalid_string").unwrap_err();
394404
assert!(error.to_string().contains(INVALID_EPOCH_SPECIFIER_ERROR));
395405
}
396406

397407
#[test]
398408
fn parse_too_big_epoch_number_yield_error() {
399-
let error = Epoch::parse_specifier(&format!("9{}", u64::MAX)).unwrap_err();
409+
let error = EpochSpecifier::parse(&format!("9{}", u64::MAX)).unwrap_err();
400410
assert!(error.to_string().contains(INVALID_EPOCH_SPECIFIER_ERROR));
401411
println!("{:?}", error);
402412
}
403413

404414
#[test]
405415
fn parse_latest_epoch_with_invalid_offset_yield_error() {
406-
let error = Epoch::parse_specifier("latest-invalid").unwrap_err();
416+
let error = EpochSpecifier::parse("latest-invalid").unwrap_err();
407417
assert!(error.to_string().contains(
408418
"Invalid epoch 'latest-invalid': offset must be a positive 64-bit integer"
409419
));
410420
}
411421

412422
#[test]
413423
fn parse_latest_epoch_with_empty_offset_yield_error() {
414-
let error = Epoch::parse_specifier("latest-").unwrap_err();
424+
let error = EpochSpecifier::parse("latest-").unwrap_err();
415425
assert!(
416426
error
417427
.to_string()
@@ -421,7 +431,7 @@ mod tests {
421431

422432
#[test]
423433
fn parse_latest_epoch_with_too_big_offset_yield_error() {
424-
let error = Epoch::parse_specifier(&format!("latest-9{}", u64::MAX)).unwrap_err();
434+
let error = EpochSpecifier::parse(&format!("latest-9{}", u64::MAX)).unwrap_err();
425435
assert!(error.to_string().contains(
426436
"Invalid epoch 'latest-918446744073709551615': offset must be a positive 64-bit integer"
427437
))
@@ -434,7 +444,7 @@ mod tests {
434444
EpochSpecifier::Latest,
435445
EpochSpecifier::LatestMinusOffset(121),
436446
] {
437-
let value = Epoch::parse_specifier(&specifier.to_string()).unwrap();
447+
let value = EpochSpecifier::parse(&specifier.to_string()).unwrap();
438448
assert_eq!(value, specifier);
439449
}
440450
}

0 commit comments

Comments
 (0)