pub(crate) struct Parser {
zulu: bool,
subminute: bool,
subsecond: bool,
}
Expand description
A parser for UTC offsets.
At time of writing, the typical configuration for offset parsing is to enable Zulu support and subminute precision. But when parsing zoned datetimes, and specifically, offsets within time zone annotations (the RFC 9557 extension to RFC 3339), then neither zulu nor subminute support are enabled.
N.B. I’m not actually totally clear on why zulu/subminute aren’t allowed in time zone annotations, but that’s what Temporal’s grammar seems to dictate. One might argue that this is what RFCs 3339 and 9557 require, but the Temporal grammar is already recognizing a superset anyway.
Fields§
§zulu: bool
§subminute: bool
§subsecond: bool
Implementations§
Source§impl Parser
impl Parser
Sourcepub(crate) const fn new() -> Parser
pub(crate) const fn new() -> Parser
Create a new UTC offset parser with the default configuration.
Sourcepub(crate) const fn zulu(self, yes: bool) -> Parser
pub(crate) const fn zulu(self, yes: bool) -> Parser
When enabled, the z
and Z
designators are recognized as a “zulu”
indicator for UTC when the civil time offset is unknown or unavailable.
When disabled, neither z
nor Z
will be recognized and a parser
error will occur if one is found.
This is enabled by default.
Sourcepub(crate) const fn subminute(self, yes: bool) -> Parser
pub(crate) const fn subminute(self, yes: bool) -> Parser
When enabled, offsets with precision greater than integral minutes are supported. Specifically, when enabled, nanosecond precision is supported.
When disabled, offsets must be integral minutes. And the subsecond
option is ignored.
Sourcepub(crate) const fn subsecond(self, yes: bool) -> Parser
pub(crate) const fn subsecond(self, yes: bool) -> Parser
When enabled, offsets with precision greater than integral seconds
are supported. Specifically, when enabled, nanosecond precision is
supported. Note though that when a fractional second is found, it is
used to round to the nearest second. (Jiff’s Offset
type only has
second resolution.)
When disabled, offsets must be integral seconds (or integrate minutes
if the subminute
option is disabled as well).
This is ignored if subminute
is disabled.
Sourcepub(crate) fn parse<'i>(
&self,
input: &'i [u8],
) -> Result<Parsed<'i, ParsedOffset>, Error>
pub(crate) fn parse<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, ParsedOffset>, Error>
Parse an offset from the beginning of input
.
If no offset could be found or it was otherwise invalid, then an error is returned.
In general, parsing stops when, after all required components are seen, an optional component is not present (either because of the end of the input or because of a character that cannot possibly begin said optional component). This does mean that there are some corner cases where error messages will not be as good as they possibly can be. But there are two exceptions here:
- When Zulu support is disabled and a
Z
orz
are found, then an error is returned indicating thatZ
was recognized but specifically not allowed. - When subminute precision is disabled and a
:
is found after the minutes component, then an error is returned indicating that the seconds component was recognized but specifically not allowed.
Otherwise, for example, if input
is -0512:34
, then the -0512
will be parsed as -5 hours, 12 minutes
with an offset of 5
.
Presumably, whatever higher level parser is invoking this routine will
then see an unexpected :
. But it’s likely that a better error message
would call out the fact that mixed basic and extended formats (from
ISO 8601) aren’t allowed, and that the offset needs to be written as
either -05:12:34
or -051234
. But… these are odd corner cases, so
we abide them.
Sourcepub(crate) fn parse_optional<'i>(
&self,
input: &'i [u8],
) -> Result<Parsed<'i, Option<ParsedOffset>>, Error>
pub(crate) fn parse_optional<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, Option<ParsedOffset>>, Error>
Like parse
, but will return None
if input
cannot possibly start
with an offset.
Basically, if input
is empty, or is not one of z
, Z
, +
or -
then this returns None
.
Sourcefn parse_numeric<'i>(
&self,
input: &'i [u8],
) -> Result<Parsed<'i, Numeric>, Error>
fn parse_numeric<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, Numeric>, Error>
Parses a numeric offset from the beginning of input
.
The beginning of the input is expected to start with a +
or a -
.
Any other case (including an empty string) will result in an error.
fn parse_sign<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, ri8<-1, 1>>, Error>
fn parse_hours<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, ri8<0, { t::SpanZoneOffsetHours::MAX }>>, Error>
fn parse_minutes<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, ri8<0, { t::SpanZoneOffsetMinutes::MAX }>>, Error>
fn parse_seconds<'i>( &self, input: &'i [u8], ) -> Result<Parsed<'i, ri8<0, { t::SpanZoneOffsetSeconds::MAX }>>, Error>
Sourcefn parse_separator<'i>(
&self,
input: &'i [u8],
extended: bool,
) -> Result<Parsed<'i, bool>, Error>
fn parse_separator<'i>( &self, input: &'i [u8], extended: bool, ) -> Result<Parsed<'i, bool>, Error>
Parses a separator between hours/minutes or minutes/seconds. When
true
is returned, we expect to parse the next component. When false
is returned, then no separator was found and there is no expectation of
finding another component.
When in extended mode, true is returned if and only if a separator is found.
When in basic mode (not extended), then a subsequent component is only
expected when input
begins with two ASCII digits.