-
Notifications
You must be signed in to change notification settings - Fork 542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flexible offset parsing [2/3] #1083
base: main
Are you sure you want to change the base?
Conversation
d622df8
to
9f4df92
Compare
src/format/parse.rs
Outdated
@@ -219,7 +220,18 @@ fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st | |||
parsed.set_nanosecond(nanosecond)?; | |||
} | |||
|
|||
let offset = try_consume!(scan::timezone_offset_zulu(s, |s| scan::char(s, b':'))); | |||
let offset = if s.starts_with("UTC") || s.starts_with("utc") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The quote from RFC 3339 in the code comment above suggests the special string to search for would be
"Z"
. Why is that not the special case here?
-
Why not search the entire remainder of the string
s
? e.g. why notif matches!(s, "UTC" | "utc") {
(also,
matches
is more succinct). Would there be a case wheres
should have trailing data after having matched the timezone in an RFC3339?
It seems like this code expression should be:
let offset = if matches!(s, "Z" | "z") {
s = &[1..];
0
} else {
...
}
if ! s.empty() {
return Err(TOO_LONG);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The quote from RFC 3339 in the code comment above suggests the special string to search for would be
"Z"
. Why is that not the special case here?
"Z" is handled by the parser. But this item does not only parse valid RFC 3339, but also supports "UTC" as offset. This is documented in https://docs.rs/chrono/latest/chrono/format/strftime/index.html#fn7. I suppose it makes some sense to support parsing this.
I'll add a comment.
- Why not search the entire remainder of the string
s
? e.g. why not
if matches!(s, "UTC" | "utc") {
(also,matches
is more succinct). Would there be a case wheres
should have trailing data after having matched the timezone in an RFC3339?
I agree it is not likely to have any data after this.
But all parsing items only consume as much as they need to. There can be other items coming after it. And otherwise it is up to the calling function decide what to do with the trailing data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Z" is handled by the parser
Oh, it's handled by scan::utc_offset(s, offset_format))
below. Gotcha.
also supports "UTC" as offset.
It is convenient but it's not strict RFC 3339, AFAICT. I'd prefer not allowing it. I won't block on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But all parsing items only consume as much as they need to.... And otherwise it is up to the calling function decide what to do with the trailing data.
Ah right, I recall now
Lines 519 to 524 in c01e3a7
// if there are trailling chars, it is an error | |
if !s.is_empty() { | |
Err((s, TOO_LONG)) | |
} else { | |
Ok(s) | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is convenient but it's not strict RFC 3339, AFAICT. I'd prefer not allowing it.
The commit tile says what I think about it 😄:
Remove hack to accept "UTC" in
timezone_offset_zulu
-
One place it is used is for the
%+
formatting item, with this description:Same as
%Y-%m-%dT%H:%M:%S%.f%:z
, i.e. 0, 3, 6 or 9 fractional digits for seconds and colons in the time zone offset.This format also supports having a
Z
orUTC
in place of%:z
. They are equivalent to+00:00
.Note that all
T
,Z
, andUTC
are parsed case-insensitively.The typical
strftime
implementations have different (and locale-dependent) formats for this specifier. While Chrono's format for%+
is far more stable, it is best to avoid this specifier if you want to control the exact output.
So being less strict here seems useful to me. -
DateTime<FixedOffset>::parse_from_rfc_3339
also uses it, and should be very strict however. -
A second RFC3339 parser is in
impl str::FromStr for DateTime<FixedOffset>
.
That one is very forgiving, which is useful there.
Maybe parsing%+
should use that implementation?
8f0e628
to
257fa20
Compare
438d354
to
86c4719
Compare
I did not realize I'll keep this PR as a draft for a little longer. #1145 has the proper fix for some changes I had to make here to RFC 3339 parsing code, and it is better if that is merged first. |
d95caa7
to
00437e5
Compare
00437e5
to
ecb572c
Compare
ecb572c
to
1eed59a
Compare
Codecov Report
@@ Coverage Diff @@
## 0.4.x #1083 +/- ##
==========================================
+ Coverage 86.10% 86.35% +0.24%
==========================================
Files 37 37
Lines 13522 13776 +254
==========================================
+ Hits 11643 11896 +253
- Misses 1879 1880 +1
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
1eed59a
to
7964d8f
Compare
refactor when chronotope/chrono#1083 will land
The first commit is shared with #1082.
Then a couple of commits do some cleanup and add a new offset parser.
All the test keep passing, except some of those for
#z
. The difference is in the error causes, which have improved a bit.Next are commits to make
%:z
,%::z
and%:::z
work as documented:%:z
should require a colon (this is what makes it different from%z
).%::z
should also be able to parse, and even require, seconds.%:::z
should only accept hours.Finally the
FromStr
implementation ofDateTime<FixedOffset>
now accepts optional seconds in the offset, so that it can parse theDebug
format ofDateTime
.TODO: I still need to figure out some way to test all the code paths of the new offset parser.