summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/format/scan.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/chrono/src/format/scan.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/chrono/src/format/scan.rs')
-rw-r--r--vendor/chrono/src/format/scan.rs121
1 files changed, 93 insertions, 28 deletions
diff --git a/vendor/chrono/src/format/scan.rs b/vendor/chrono/src/format/scan.rs
index 0efb1ee3d..263fec556 100644
--- a/vendor/chrono/src/format/scan.rs
+++ b/vendor/chrono/src/format/scan.rs
@@ -8,13 +8,13 @@
#![allow(deprecated)]
use super::{ParseResult, INVALID, OUT_OF_RANGE, TOO_SHORT};
-use Weekday;
+use crate::Weekday;
/// Returns true when two slices are equal case-insensitively (in ASCII).
/// Assumes that the `pattern` is already converted to lower case.
fn equals(s: &str, pattern: &str) -> bool {
let mut xs = s.as_bytes().iter().map(|&c| match c {
- b'A'...b'Z' => c + 32,
+ b'A'..=b'Z' => c + 32,
_ => c,
});
let mut ys = pattern.as_bytes().iter().cloned();
@@ -34,7 +34,7 @@ fn equals(s: &str, pattern: &str) -> bool {
/// More than `max` digits are consumed up to the first `max` digits.
/// Any number that does not fit in `i64` is an error.
#[inline]
-pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> {
+pub(super) fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> {
assert!(min <= max);
// We are only interested in ascii numbers, so we can work with the `str` as bytes. We stop on
@@ -48,7 +48,7 @@ pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> {
let mut n = 0i64;
for (i, c) in bytes.iter().take(max).cloned().enumerate() {
// cloned() = copied()
- if c < b'0' || b'9' < c {
+ if !(b'0'..=b'9').contains(&c) {
if i < min {
return Err(INVALID);
} else {
@@ -62,12 +62,12 @@ pub fn number(s: &str, min: usize, max: usize) -> ParseResult<(&str, i64)> {
};
}
- Ok((&s[::core::cmp::min(max, bytes.len())..], n))
+ Ok((&s[core::cmp::min(max, bytes.len())..], n))
}
/// Tries to consume at least one digits as a fractional second.
/// Returns the number of whole nanoseconds (0--999,999,999).
-pub fn nanosecond(s: &str) -> ParseResult<(&str, i64)> {
+pub(super) fn nanosecond(s: &str) -> ParseResult<(&str, i64)> {
// record the number of digits consumed for later scaling.
let origlen = s.len();
let (s, v) = number(s, 1, 9)?;
@@ -79,14 +79,14 @@ pub fn nanosecond(s: &str) -> ParseResult<(&str, i64)> {
let v = v.checked_mul(SCALE[consumed]).ok_or(OUT_OF_RANGE)?;
// if there are more than 9 digits, skip next digits.
- let s = s.trim_left_matches(|c: char| '0' <= c && c <= '9');
+ let s = s.trim_left_matches(|c: char| ('0'..='9').contains(&c));
Ok((s, v))
}
/// Tries to consume a fixed number of digits as a fractional second.
/// Returns the number of whole nanoseconds (0--999,999,999).
-pub fn nanosecond_fixed(s: &str, digits: usize) -> ParseResult<(&str, i64)> {
+pub(super) fn nanosecond_fixed(s: &str, digits: usize) -> ParseResult<(&str, i64)> {
// record the number of digits consumed for later scaling.
let (s, v) = number(s, digits, digits)?;
@@ -99,7 +99,7 @@ pub fn nanosecond_fixed(s: &str, digits: usize) -> ParseResult<(&str, i64)> {
}
/// Tries to parse the month index (0 through 11) with the first three ASCII letters.
-pub fn short_month0(s: &str) -> ParseResult<(&str, u8)> {
+pub(super) fn short_month0(s: &str) -> ParseResult<(&str, u8)> {
if s.len() < 3 {
return Err(TOO_SHORT);
}
@@ -123,7 +123,7 @@ pub fn short_month0(s: &str) -> ParseResult<(&str, u8)> {
}
/// Tries to parse the weekday with the first three ASCII letters.
-pub fn short_weekday(s: &str) -> ParseResult<(&str, Weekday)> {
+pub(super) fn short_weekday(s: &str) -> ParseResult<(&str, Weekday)> {
if s.len() < 3 {
return Err(TOO_SHORT);
}
@@ -143,9 +143,9 @@ pub fn short_weekday(s: &str) -> ParseResult<(&str, Weekday)> {
/// Tries to parse the month index (0 through 11) with short or long month names.
/// It prefers long month names to short month names when both are possible.
-pub fn short_or_long_month0(s: &str) -> ParseResult<(&str, u8)> {
+pub(super) fn short_or_long_month0(s: &str) -> ParseResult<(&str, u8)> {
// lowercased month names, minus first three chars
- static LONG_MONTH_SUFFIXES: [&'static str; 12] =
+ static LONG_MONTH_SUFFIXES: [&str; 12] =
["uary", "ruary", "ch", "il", "", "e", "y", "ust", "tember", "ober", "ember", "ember"];
let (mut s, month0) = short_month0(s)?;
@@ -161,9 +161,9 @@ pub fn short_or_long_month0(s: &str) -> ParseResult<(&str, u8)> {
/// Tries to parse the weekday with short or long weekday names.
/// It prefers long weekday names to short weekday names when both are possible.
-pub fn short_or_long_weekday(s: &str) -> ParseResult<(&str, Weekday)> {
+pub(super) fn short_or_long_weekday(s: &str) -> ParseResult<(&str, Weekday)> {
// lowercased weekday names, minus first three chars
- static LONG_WEEKDAY_SUFFIXES: [&'static str; 7] =
+ static LONG_WEEKDAY_SUFFIXES: [&str; 7] =
["day", "sday", "nesday", "rsday", "day", "urday", "day"];
let (mut s, weekday) = short_weekday(s)?;
@@ -178,7 +178,7 @@ pub fn short_or_long_weekday(s: &str) -> ParseResult<(&str, Weekday)> {
}
/// Tries to consume exactly one given character.
-pub fn char(s: &str, c1: u8) -> ParseResult<&str> {
+pub(super) fn char(s: &str, c1: u8) -> ParseResult<&str> {
match s.as_bytes().first() {
Some(&c) if c == c1 => Ok(&s[1..]),
Some(_) => Err(INVALID),
@@ -187,7 +187,7 @@ pub fn char(s: &str, c1: u8) -> ParseResult<&str> {
}
/// Tries to consume one or more whitespace.
-pub fn space(s: &str) -> ParseResult<&str> {
+pub(super) fn space(s: &str) -> ParseResult<&str> {
let s_ = s.trim_left();
if s_.len() < s.len() {
Ok(s_)
@@ -199,7 +199,7 @@ pub fn space(s: &str) -> ParseResult<&str> {
}
/// Consumes any number (including zero) of colon or spaces.
-pub fn colon_or_space(s: &str) -> ParseResult<&str> {
+pub(super) fn colon_or_space(s: &str) -> ParseResult<&str> {
Ok(s.trim_left_matches(|c: char| c == ':' || c.is_whitespace()))
}
@@ -207,7 +207,7 @@ pub fn colon_or_space(s: &str) -> ParseResult<&str> {
///
/// The additional `colon` may be used to parse a mandatory or optional `:`
/// between hours and minutes, and should return either a new suffix or `Err` when parsing fails.
-pub fn timezone_offset<F>(s: &str, consume_colon: F) -> ParseResult<(&str, i32)>
+pub(super) fn timezone_offset<F>(s: &str, consume_colon: F) -> ParseResult<(&str, i32)>
where
F: FnMut(&str) -> ParseResult<&str>,
{
@@ -240,7 +240,7 @@ where
// 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')),
+ (h1 @ b'0'..=b'9', h2 @ b'0'..=b'9') => i32::from((h1 - b'0') * 10 + (h2 - b'0')),
_ => return Err(INVALID),
};
s = &s[2..];
@@ -252,8 +252,8 @@ where
// 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),
+ (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),
}
} else if allow_missing_minutes {
@@ -272,7 +272,7 @@ where
}
/// Same as `timezone_offset` but also allows for `z`/`Z` which is the same as `+00:00`.
-pub fn timezone_offset_zulu<F>(s: &str, colon: F) -> ParseResult<(&str, i32)>
+pub(super) fn timezone_offset_zulu<F>(s: &str, colon: F) -> ParseResult<(&str, i32)>
where
F: FnMut(&str) -> ParseResult<&str>,
{
@@ -296,7 +296,7 @@ where
/// Same as `timezone_offset` but also allows for `z`/`Z` which is the same as
/// `+00:00`, and allows missing minutes entirely.
-pub fn timezone_offset_permissive<F>(s: &str, colon: F) -> ParseResult<(&str, i32)>
+pub(super) fn timezone_offset_permissive<F>(s: &str, colon: F) -> ParseResult<(&str, i32)>
where
F: FnMut(&str) -> ParseResult<&str>,
{
@@ -308,16 +308,16 @@ where
/// Same as `timezone_offset` but also allows for RFC 2822 legacy timezones.
/// May return `None` which indicates an insufficient offset data (i.e. `-0000`).
-pub fn timezone_offset_2822(s: &str) -> ParseResult<(&str, Option<i32>)> {
+pub(super) fn timezone_offset_2822(s: &str) -> ParseResult<(&str, Option<i32>)> {
// tries to parse legacy time zone names
let upto = s
.as_bytes()
.iter()
.position(|&c| match c {
- b'a'...b'z' | b'A'...b'Z' => false,
+ b'a'..=b'z' | b'A'..=b'Z' => false,
_ => true,
})
- .unwrap_or_else(|| s.len());
+ .unwrap_or(s.len());
if upto > 0 {
let name = &s[..upto];
let s = &s[upto..];
@@ -343,8 +343,73 @@ pub fn timezone_offset_2822(s: &str) -> ParseResult<(&str, Option<i32>)> {
}
}
-/// Tries to consume everyting until next whitespace-like symbol.
+/// Tries to consume everything until next whitespace-like symbol.
/// Does not provide any offset information from the consumed data.
-pub fn timezone_name_skip(s: &str) -> ParseResult<(&str, ())> {
+pub(super) fn timezone_name_skip(s: &str) -> ParseResult<(&str, ())> {
Ok((s.trim_left_matches(|c: char| !c.is_whitespace()), ()))
}
+
+/// Tries to consume an RFC2822 comment including preceding ` `.
+///
+/// Returns the remaining string after the closing parenthesis.
+pub(super) fn comment_2822(s: &str) -> ParseResult<(&str, ())> {
+ use CommentState::*;
+
+ let s = s.trim_start();
+
+ let mut state = Start;
+ for (i, c) in s.bytes().enumerate() {
+ state = match (state, c) {
+ (Start, b'(') => Next(1),
+ (Next(1), b')') => return Ok((&s[i + 1..], ())),
+ (Next(depth), b'\\') => Escape(depth),
+ (Next(depth), b'(') => Next(depth + 1),
+ (Next(depth), b')') => Next(depth - 1),
+ (Next(depth), _) | (Escape(depth), _) => Next(depth),
+ _ => return Err(INVALID),
+ };
+ }
+
+ Err(TOO_SHORT)
+}
+
+enum CommentState {
+ Start,
+ Next(usize),
+ Escape(usize),
+}
+
+#[cfg(test)]
+#[test]
+fn test_rfc2822_comments() {
+ let testdata = [
+ ("", Err(TOO_SHORT)),
+ (" ", Err(TOO_SHORT)),
+ ("x", Err(INVALID)),
+ ("(", Err(TOO_SHORT)),
+ ("()", Ok("")),
+ (" \r\n\t()", Ok("")),
+ ("() ", Ok(" ")),
+ ("()z", Ok("z")),
+ ("(x)", Ok("")),
+ ("(())", Ok("")),
+ ("((()))", Ok("")),
+ ("(x(x(x)x)x)", Ok("")),
+ ("( x ( x ( x ) x ) x )", Ok("")),
+ (r"(\)", Err(TOO_SHORT)),
+ (r"(\()", Ok("")),
+ (r"(\))", Ok("")),
+ (r"(\\)", Ok("")),
+ ("(()())", Ok("")),
+ ("( x ( x ) x ( x ) x )", Ok("")),
+ ];
+
+ for (test_in, expected) in testdata.iter() {
+ let actual = comment_2822(test_in).map(|(s, _)| s);
+ assert_eq!(
+ *expected, actual,
+ "{:?} expected to produce {:?}, but produced {:?}.",
+ test_in, expected, actual
+ );
+ }
+}