Skip to content

Commit 5304354

Browse files
committed
Simplify digit parsing in timezone_offset
1 parent b636fcf commit 5304354

File tree

2 files changed

+18
-34
lines changed

2 files changed

+18
-34
lines changed

src/format/parse.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ mod tests {
12921292
check("12345678", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
12931293
check("+1", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_SHORT));
12941294
check("+12", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 43_200));
1295-
check("+123", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_SHORT));
1295+
check("+123", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
12961296
check("+1234", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 45_240));
12971297
check("-1234", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240));
12981298
check("−1234", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240)); // MINUS SIGN (U+2212)
@@ -1309,7 +1309,7 @@ mod tests {
13091309
check("12:34:56", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
13101310
check("+1:", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
13111311
check("+12:", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 43_200));
1312-
check("+12:3", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_SHORT));
1312+
check("+12:3", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
13131313
check("+12:34", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 45_240));
13141314
check("-12:34", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240));
13151315
check("−12:34", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240)); // MINUS SIGN (U+2212)
@@ -1359,7 +1359,7 @@ mod tests {
13591359
);
13601360
check("🤠+12:34", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
13611361
check("+12:34🤠", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
1362-
check("+12:🤠34", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
1362+
check("+12:🤠34", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
13631363
check(
13641364
"+12:34🤠",
13651365
&[internal_fixed(TimezoneOffsetPermissive), Literal("🤠")],

src/format/scan.rs

+15-31
Original file line numberDiff line numberDiff line change
@@ -215,67 +215,51 @@ where
215215
}
216216
}
217217

218-
const fn digits(s: &str) -> ParseResult<(u8, u8)> {
218+
fn digits(s: &str) -> ParseResult<u8> {
219219
let b = s.as_bytes();
220220
if b.len() < 2 {
221-
Err(TOO_SHORT)
222-
} else {
223-
Ok((b[0], b[1]))
221+
return Err(TOO_SHORT);
222+
}
223+
match (b[0], b[1]) {
224+
(h1 @ b'0'..=b'9', h2 @ b'0'..=b'9') => Ok((h1 - b'0') * 10 + (h2 - b'0')),
225+
_ => Err(INVALID),
224226
}
225227
}
226228
let negative = match s.chars().next() {
227229
Some('+') => {
228-
// PLUS SIGN (U+2B)
229230
s = &s['+'.len_utf8()..];
230-
231231
false
232232
}
233233
Some('-') => {
234-
// HYPHEN-MINUS (U+2D)
235234
s = &s['-'.len_utf8()..];
236-
237235
true
238236
}
239-
Some('−') => {
237+
Some('−') if allow_tz_minus_sign => {
240238
// MINUS SIGN (U+2212)
241-
if !allow_tz_minus_sign {
242-
return Err(INVALID);
243-
}
244239
s = &s['−'.len_utf8()..];
245-
246240
true
247241
}
248242
Some(_) => return Err(INVALID),
249243
None => return Err(TOO_SHORT),
250244
};
251245

252246
// hours (00--99)
253-
let hours = match digits(s)? {
254-
(h1 @ b'0'..=b'9', h2 @ b'0'..=b'9') => i32::from((h1 - b'0') * 10 + (h2 - b'0')),
255-
_ => return Err(INVALID),
256-
};
247+
let hours = digits(s)? as i32;
257248
s = &s[2..];
258249

259250
// colons (and possibly other separators)
260251
s = consume_colon(s)?;
261252

262253
// minutes (00--59)
263254
// if the next two items are digits then we have to add minutes
264-
let minutes = if let Ok(ds) = digits(s) {
265-
match ds {
266-
(m1 @ b'0'..=b'5', m2 @ b'0'..=b'9') => i32::from((m1 - b'0') * 10 + (m2 - b'0')),
267-
(b'6'..=b'9', b'0'..=b'9') => return Err(OUT_OF_RANGE),
268-
_ => return Err(INVALID),
255+
let minutes = match digits(s) {
256+
Ok(m) if m >= 60 => return Err(OUT_OF_RANGE),
257+
Ok(m) => {
258+
s = &s[2..];
259+
m as i32
269260
}
270-
} else if allow_missing_minutes {
271-
0
272-
} else {
273-
return Err(TOO_SHORT);
274-
};
275-
s = match s.len() {
276-
len if len >= 2 => &s[2..],
277-
0 => s,
278-
_ => return Err(TOO_SHORT),
261+
Err(_) if allow_missing_minutes => 0,
262+
Err(e) => return Err(e),
279263
};
280264

281265
let seconds = hours * 3600 + minutes * 60;

0 commit comments

Comments
 (0)