@@ -52,6 +52,17 @@ use std::time::Duration;
5252/// assert_eq!(from_str("2d"), Ok(Duration::from_secs(60 * 60 * 24 * 2)));
5353/// ```
5454pub fn from_str ( string : & str ) -> Result < Duration , String > {
55+ from_str_inner (
56+ string,
57+ & [ ( 's' , 1 ) , ( 'm' , 60 ) , ( 'h' , 60 * 60 ) , ( 'd' , 60 * 60 * 24 ) ] ,
58+ )
59+ }
60+
61+ pub fn from_str_without_suffix ( string : & str ) -> Result < Duration , String > {
62+ from_str_inner ( string, & [ ] )
63+ }
64+
65+ fn from_str_inner ( string : & str , allowed_suffixes : & [ ( char , u32 ) ] ) -> Result < Duration , String > {
5566 // TODO: Switch to Duration::NANOSECOND if that ever becomes stable
5667 // https://github.com/rust-lang/rust/issues/57391
5768 const NANOSECOND_DURATION : Duration = Duration :: from_nanos ( 1 ) ;
@@ -60,11 +71,7 @@ pub fn from_str(string: &str) -> Result<Duration, String> {
6071 if len == 0 {
6172 return Err ( format ! ( "invalid time interval {}" , string. quote( ) ) ) ;
6273 }
63- let num = match num_parser:: parse (
64- string,
65- ParseTarget :: Duration ,
66- & [ ( 's' , 1 ) , ( 'm' , 60 ) , ( 'h' , 60 * 60 ) , ( 'd' , 60 * 60 * 24 ) ] ,
67- ) {
74+ let num = match num_parser:: parse ( string, ParseTarget :: Duration , allowed_suffixes) {
6875 Ok ( ebd) | Err ( ExtendedParserError :: Overflow ( ebd) ) => ebd,
6976 Err ( ExtendedParserError :: Underflow ( _) ) => return Ok ( NANOSECOND_DURATION ) ,
7077 _ => {
@@ -100,17 +107,19 @@ pub fn from_str(string: &str) -> Result<Duration, String> {
100107#[ cfg( test) ]
101108mod tests {
102109
103- use crate :: parser:: parse_time:: from_str;
110+ use crate :: parser:: parse_time:: { from_str, from_str_without_suffix } ;
104111 use std:: time:: Duration ;
105112
106113 #[ test]
107114 fn test_no_units ( ) {
108115 assert_eq ! ( from_str( "123" ) , Ok ( Duration :: from_secs( 123 ) ) ) ;
116+ assert_eq ! ( from_str_without_suffix( "123" ) , Ok ( Duration :: from_secs( 123 ) ) ) ;
109117 }
110118
111119 #[ test]
112120 fn test_units ( ) {
113121 assert_eq ! ( from_str( "2d" ) , Ok ( Duration :: from_secs( 60 * 60 * 24 * 2 ) ) ) ;
122+ assert ! ( from_str_without_suffix( "2d" ) . is_err( ) ) ;
114123 }
115124
116125 #[ test]
@@ -119,6 +128,10 @@ mod tests {
119128 assert_eq ! ( from_str( "9223372036854775808d" ) , Ok ( Duration :: MAX ) ) ;
120129 // ExtendedBigDecimal overflow
121130 assert_eq ! ( from_str( "1e92233720368547758080" ) , Ok ( Duration :: MAX ) ) ;
131+ assert_eq ! (
132+ from_str_without_suffix( "1e92233720368547758080" ) ,
133+ Ok ( Duration :: MAX )
134+ ) ;
122135 }
123136
124137 #[ test]
@@ -136,6 +149,22 @@ mod tests {
136149 assert_eq ! ( from_str( "1e-9" ) , Ok ( NANOSECOND_DURATION ) ) ;
137150 assert_eq ! ( from_str( "1.9e-9" ) , Ok ( NANOSECOND_DURATION ) ) ;
138151 assert_eq ! ( from_str( "2e-9" ) , Ok ( Duration :: from_nanos( 2 ) ) ) ;
152+
153+ // ExtendedBigDecimal underflow
154+ assert_eq ! (
155+ from_str_without_suffix( "1e-92233720368547758080" ) ,
156+ Ok ( NANOSECOND_DURATION )
157+ ) ;
158+ // nanoseconds underflow (in Duration)
159+ assert_eq ! (
160+ from_str_without_suffix( "0.0000000001" ) ,
161+ Ok ( NANOSECOND_DURATION )
162+ ) ;
163+ assert_eq ! ( from_str_without_suffix( "1e-10" ) , Ok ( NANOSECOND_DURATION ) ) ;
164+ assert_eq ! ( from_str_without_suffix( "9e-10" ) , Ok ( NANOSECOND_DURATION ) ) ;
165+ assert_eq ! ( from_str_without_suffix( "1e-9" ) , Ok ( NANOSECOND_DURATION ) ) ;
166+ assert_eq ! ( from_str_without_suffix( "1.9e-9" ) , Ok ( NANOSECOND_DURATION ) ) ;
167+ assert_eq ! ( from_str_without_suffix( "2e-9" ) , Ok ( Duration :: from_nanos( 2 ) ) ) ;
139168 }
140169
141170 #[ test]
@@ -144,6 +173,17 @@ mod tests {
144173 assert_eq ! ( from_str( "0e-100" ) , Ok ( Duration :: ZERO ) ) ;
145174 assert_eq ! ( from_str( "0e-92233720368547758080" ) , Ok ( Duration :: ZERO ) ) ;
146175 assert_eq ! ( from_str( "0.000000000000000000000" ) , Ok ( Duration :: ZERO ) ) ;
176+
177+ assert_eq ! ( from_str_without_suffix( "0e-9" ) , Ok ( Duration :: ZERO ) ) ;
178+ assert_eq ! ( from_str_without_suffix( "0e-100" ) , Ok ( Duration :: ZERO ) ) ;
179+ assert_eq ! (
180+ from_str_without_suffix( "0e-92233720368547758080" ) ,
181+ Ok ( Duration :: ZERO )
182+ ) ;
183+ assert_eq ! (
184+ from_str_without_suffix( "0.000000000000000000000" ) ,
185+ Ok ( Duration :: ZERO )
186+ ) ;
147187 }
148188
149189 #[ test]
@@ -152,6 +192,10 @@ mod tests {
152192 from_str( "0x1.1p-1" ) ,
153193 Ok ( Duration :: from_secs_f64( 0.53125f64 ) )
154194 ) ;
195+ assert_eq ! (
196+ from_str_without_suffix( "0x1.1p-1" ) ,
197+ Ok ( Duration :: from_secs_f64( 0.53125f64 ) )
198+ ) ;
155199 assert_eq ! (
156200 from_str( "0x1.1p-1d" ) ,
157201 Ok ( Duration :: from_secs_f64( 0.53125f64 * 3600.0 * 24.0 ) )
@@ -162,26 +206,37 @@ mod tests {
162206 #[ test]
163207 fn test_error_empty ( ) {
164208 assert ! ( from_str( "" ) . is_err( ) ) ;
209+ assert ! ( from_str_without_suffix( "" ) . is_err( ) ) ;
165210 }
166211
167212 #[ test]
168213 fn test_error_invalid_unit ( ) {
169214 assert ! ( from_str( "123X" ) . is_err( ) ) ;
215+ assert ! ( from_str_without_suffix( "123X" ) . is_err( ) ) ;
170216 }
171217
172218 #[ test]
173219 fn test_error_multi_bytes_characters ( ) {
174220 assert ! ( from_str( "10€" ) . is_err( ) ) ;
221+ assert ! ( from_str_without_suffix( "10€" ) . is_err( ) ) ;
175222 }
176223
177224 #[ test]
178225 fn test_error_invalid_magnitude ( ) {
179226 assert ! ( from_str( "12abc3s" ) . is_err( ) ) ;
227+ assert ! ( from_str_without_suffix( "12abc3s" ) . is_err( ) ) ;
228+ }
229+
230+ #[ test]
231+ fn test_error_only_point ( ) {
232+ assert ! ( from_str( "." ) . is_err( ) ) ;
233+ assert ! ( from_str_without_suffix( "." ) . is_err( ) ) ;
180234 }
181235
182236 #[ test]
183237 fn test_negative ( ) {
184238 assert ! ( from_str( "-1" ) . is_err( ) ) ;
239+ assert ! ( from_str_without_suffix( "-1" ) . is_err( ) ) ;
185240 }
186241
187242 #[ test]
@@ -191,6 +246,10 @@ mod tests {
191246 assert_eq ! ( from_str( "infinityh" ) , Ok ( Duration :: MAX ) ) ;
192247 assert_eq ! ( from_str( "INF" ) , Ok ( Duration :: MAX ) ) ;
193248 assert_eq ! ( from_str( "INFs" ) , Ok ( Duration :: MAX ) ) ;
249+
250+ assert_eq ! ( from_str_without_suffix( "inf" ) , Ok ( Duration :: MAX ) ) ;
251+ assert_eq ! ( from_str_without_suffix( "infinity" ) , Ok ( Duration :: MAX ) ) ;
252+ assert_eq ! ( from_str_without_suffix( "INF" ) , Ok ( Duration :: MAX ) ) ;
194253 }
195254
196255 #[ test]
@@ -200,6 +259,10 @@ mod tests {
200259 assert ! ( from_str( "-nanh" ) . is_err( ) ) ;
201260 assert ! ( from_str( "NAN" ) . is_err( ) ) ;
202261 assert ! ( from_str( "-NAN" ) . is_err( ) ) ;
262+
263+ assert ! ( from_str_without_suffix( "nan" ) . is_err( ) ) ;
264+ assert ! ( from_str_without_suffix( "NAN" ) . is_err( ) ) ;
265+ assert ! ( from_str_without_suffix( "-NAN" ) . is_err( ) ) ;
203266 }
204267
205268 /// Test that capital letters are not allowed in suffixes.
0 commit comments