Skip to content

Commit

Permalink
Simplify digit parsing in timezone_offset
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Mar 2, 2024
1 parent b636fcf commit 5304354
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 34 deletions.
6 changes: 3 additions & 3 deletions src/format/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,7 @@ mod tests {
check("12345678", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
check("+1", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_SHORT));
check("+12", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 43_200));
check("+123", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_SHORT));
check("+123", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
check("+1234", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 45_240));
check("-1234", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240));
check("−1234", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240)); // MINUS SIGN (U+2212)
Expand All @@ -1309,7 +1309,7 @@ mod tests {
check("12:34:56", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
check("+1:", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
check("+12:", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 43_200));
check("+12:3", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_SHORT));
check("+12:3", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
check("+12:34", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: 45_240));
check("-12:34", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240));
check("−12:34", &[internal_fixed(TimezoneOffsetPermissive)], parsed!(offset: -45_240)); // MINUS SIGN (U+2212)
Expand Down Expand Up @@ -1359,7 +1359,7 @@ mod tests {
);
check("🤠+12:34", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
check("+12:34🤠", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
check("+12:🤠34", &[internal_fixed(TimezoneOffsetPermissive)], Err(INVALID));
check("+12:🤠34", &[internal_fixed(TimezoneOffsetPermissive)], Err(TOO_LONG));
check(
"+12:34🤠",
&[internal_fixed(TimezoneOffsetPermissive), Literal("🤠")],
Expand Down
46 changes: 15 additions & 31 deletions src/format/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,67 +215,51 @@ where
}
}

const fn digits(s: &str) -> ParseResult<(u8, u8)> {
fn digits(s: &str) -> ParseResult<u8> {
let b = s.as_bytes();
if b.len() < 2 {
Err(TOO_SHORT)
} else {
Ok((b[0], b[1]))
return Err(TOO_SHORT);
}
match (b[0], b[1]) {
(h1 @ b'0'..=b'9', h2 @ b'0'..=b'9') => Ok((h1 - b'0') * 10 + (h2 - b'0')),
_ => Err(INVALID),
}
}
let negative = match s.chars().next() {
Some('+') => {
// PLUS SIGN (U+2B)
s = &s['+'.len_utf8()..];

false
}
Some('-') => {
// HYPHEN-MINUS (U+2D)
s = &s['-'.len_utf8()..];

true
}
Some('−') => {
Some('−') if allow_tz_minus_sign => {
// MINUS SIGN (U+2212)
if !allow_tz_minus_sign {
return Err(INVALID);
}
s = &s['−'.len_utf8()..];

true
}
Some(_) => return Err(INVALID),
None => return Err(TOO_SHORT),
};

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

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

// minutes (00--59)
// if the next two items are digits then we have to add minutes
let minutes = if let Ok(ds) = digits(s) {
match ds {
(m1 @ b'0'..=b'5', m2 @ b'0'..=b'9') => i32::from((m1 - b'0') * 10 + (m2 - b'0')),
(b'6'..=b'9', b'0'..=b'9') => return Err(OUT_OF_RANGE),
_ => return Err(INVALID),
let minutes = match digits(s) {
Ok(m) if m >= 60 => return Err(OUT_OF_RANGE),
Ok(m) => {
s = &s[2..];
m as i32
}
} else if allow_missing_minutes {
0
} else {
return Err(TOO_SHORT);
};
s = match s.len() {
len if len >= 2 => &s[2..],
0 => s,
_ => return Err(TOO_SHORT),
Err(_) if allow_missing_minutes => 0,
Err(e) => return Err(e),
};

let seconds = hours * 3600 + minutes * 60;
Expand Down

0 comments on commit 5304354

Please sign in to comment.