@@ -61,10 +61,8 @@ pub struct Duration(std::time::Duration);
61
61
impl FromStr for Duration {
62
62
type Err = DurationParseError ;
63
63
64
- fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
64
+ fn from_str ( input : & str ) -> Result < Self , Self :: Err > {
65
65
use duration_parse_error:: * ;
66
- let input = s. trim ( ) ;
67
-
68
66
if input. is_empty ( ) {
69
67
return EmptyInputSnafu . fail ( ) ;
70
68
}
@@ -76,12 +74,15 @@ impl FromStr for Duration {
76
74
let mut take_group = |f : fn ( char ) -> bool | {
77
75
let & ( from, _) = chars. peek ( ) ?;
78
76
let mut to = from;
77
+ let mut last_char = None ;
79
78
80
- while let Some ( ( i, _ ) ) = chars. next_if ( |( _, c) | f ( * c) ) {
79
+ while let Some ( ( i, c ) ) = chars. next_if ( |( _, c) | f ( * c) ) {
81
80
to = i;
81
+ last_char = Some ( c) ;
82
82
}
83
83
84
- Some ( & input[ from..=to] )
84
+ // if last_char == None then we read 0 characters => fail
85
+ Some ( & input[ from..( to + last_char?. len_utf8 ( ) ) ] )
85
86
} ;
86
87
87
88
while let Some ( value) = take_group ( char:: is_numeric) {
@@ -326,8 +327,9 @@ mod test {
326
327
#[ rstest]
327
328
#[ case( "1D" , DurationParseError :: ParseUnitError { unit: "D" . into( ) } ) ]
328
329
#[ case( "2d2" , DurationParseError :: NoUnit { value: 2 } ) ]
329
- #[ case( "1ä" , DurationParseError :: EmptyInput ) ]
330
- #[ case( " " , DurationParseError :: EmptyInput ) ]
330
+ #[ case( "1ä" , DurationParseError :: ParseUnitError { unit: "ä" . into( ) } ) ]
331
+ #[ case( " " , DurationParseError :: UnexpectedCharacter { chr: ' ' } ) ]
332
+ #[ case( "" , DurationParseError :: EmptyInput ) ]
331
333
fn parse_invalid ( #[ case] input : & str , #[ case] expected_err : DurationParseError ) {
332
334
let err = Duration :: from_str ( input) . unwrap_err ( ) ;
333
335
assert_eq ! ( err, expected_err)
0 commit comments