@@ -7,10 +7,10 @@ use anyhow::Context;
77use serde:: { Deserialize , Serialize } ;
88use thiserror:: Error ;
99
10- use crate :: StdResult ;
1110use 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
1515const 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
137111impl 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+
212222impl 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