@@ -133,23 +133,33 @@ fn extract_bucket_interval(func: &ast::Function) -> Result<i64> {
133133 Ok ( parse_interval_to_ms ( & interval_str) )
134134}
135135
136- /// Parse an interval string like "1h", "15m", "30s", "1d" to milliseconds.
136+ /// Parse an interval string to milliseconds.
137+ ///
138+ /// Accepted forms: `"1h"`, `"15m"`, `"30s"`, `"1d"`, `"1 hour"`, `"15 minutes"`,
139+ /// `"30 seconds"`, `"7 days"`. Plural and singular word forms both work.
137140fn parse_interval_to_ms ( s : & str ) -> i64 {
138141 let s = s. trim ( ) ;
139142 if s. is_empty ( ) {
140143 return 0 ;
141144 }
142- let ( num_str, suffix) = s. split_at ( s. len ( ) - 1 ) ;
143- let num: i64 = num_str. trim ( ) . parse ( ) . unwrap_or ( 0 ) ;
144- match suffix {
145- "s" => num * 1_000 ,
146- "m" => num * 60_000 ,
147- "h" => num * 3_600_000 ,
148- "d" => num * 86_400_000 ,
149- _ => {
150- // Try full string as seconds.
151- s. parse :: < i64 > ( ) . unwrap_or ( 0 ) * 1_000
145+
146+ // Split into numeric part and unit part (handles both "1h" and "1 hour").
147+ let num_end = s
148+ . find ( |c : char | !c. is_ascii_digit ( ) && c != '.' )
149+ . unwrap_or ( s. len ( ) ) ;
150+ let num: i64 = s[ ..num_end] . trim ( ) . parse ( ) . unwrap_or ( 0 ) ;
151+ let unit = s[ num_end..] . trim ( ) ;
152+
153+ match unit {
154+ "s" | "sec" | "second" | "seconds" => num * 1_000 ,
155+ "m" | "min" | "minute" | "minutes" => num * 60_000 ,
156+ "h" | "hr" | "hour" | "hours" => num * 3_600_000 ,
157+ "d" | "day" | "days" => num * 86_400_000 ,
158+ "" => {
159+ // Bare number — treat as seconds.
160+ num * 1_000
152161 }
162+ _ => 0 ,
153163 }
154164}
155165
@@ -260,5 +270,12 @@ mod tests {
260270 assert_eq ! ( parse_interval_to_ms( "15m" ) , 900_000 ) ;
261271 assert_eq ! ( parse_interval_to_ms( "30s" ) , 30_000 ) ;
262272 assert_eq ! ( parse_interval_to_ms( "7d" ) , 604_800_000 ) ;
273+ // Word-form intervals.
274+ assert_eq ! ( parse_interval_to_ms( "1 hour" ) , 3_600_000 ) ;
275+ assert_eq ! ( parse_interval_to_ms( "2 hours" ) , 7_200_000 ) ;
276+ assert_eq ! ( parse_interval_to_ms( "15 minutes" ) , 900_000 ) ;
277+ assert_eq ! ( parse_interval_to_ms( "30 seconds" ) , 30_000 ) ;
278+ assert_eq ! ( parse_interval_to_ms( "1 day" ) , 86_400_000 ) ;
279+ assert_eq ! ( parse_interval_to_ms( "5 min" ) , 300_000 ) ;
263280 }
264281}
0 commit comments