Use the `InternalFixed` struct for TimezoneOffsetPermissive
It is the backcompat scheme that we have. In the 5.x timeline we will add the more-standard and significantly-more-pleasant-to-expand `#[doc(hidden)] __DoNotMatchAgainstMe` trick.
This commit is contained in:
parent
9991c2b0ed
commit
c3207a5811
|
@ -200,15 +200,6 @@ pub enum Fixed {
|
||||||
/// Same to [`TimezoneOffsetColonZ`](#variant.TimezoneOffsetColonZ) but prints no colon.
|
/// Same to [`TimezoneOffsetColonZ`](#variant.TimezoneOffsetColonZ) but prints no colon.
|
||||||
/// Parsing allows an optional colon.
|
/// Parsing allows an optional colon.
|
||||||
TimezoneOffsetZ,
|
TimezoneOffsetZ,
|
||||||
/// Same as [`TimezoneOffsetColonZ`](#variant.TimezoneOffsetColonZ), but
|
|
||||||
/// allows missing minutes (per [ISO 8601][iso8601]).
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// If you try to use this for printing.
|
|
||||||
///
|
|
||||||
/// [iso8601]: https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC
|
|
||||||
TimezoneOffsetPermissive,
|
|
||||||
/// RFC 2822 date and time syntax. Commonly used for email and MIME date and time.
|
/// RFC 2822 date and time syntax. Commonly used for email and MIME date and time.
|
||||||
RFC2822,
|
RFC2822,
|
||||||
/// RFC 3339 & ISO 8601 date and time syntax.
|
/// RFC 3339 & ISO 8601 date and time syntax.
|
||||||
|
@ -222,29 +213,22 @@ pub enum Fixed {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An opaque type representing fixed-format item types for internal uses only.
|
/// An opaque type representing fixed-format item types for internal uses only.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct InternalFixed {
|
pub struct InternalFixed {
|
||||||
_dummy: Void,
|
val: InternalInternal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for InternalFixed {
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
fn clone(&self) -> Self {
|
enum InternalInternal {
|
||||||
match self._dummy {}
|
/// Same as [`TimezoneOffsetColonZ`](#variant.TimezoneOffsetColonZ), but
|
||||||
}
|
/// allows missing minutes (per [ISO 8601][iso8601]).
|
||||||
}
|
///
|
||||||
|
/// # Panics
|
||||||
impl PartialEq for InternalFixed {
|
///
|
||||||
fn eq(&self, _other: &InternalFixed) -> bool {
|
/// If you try to use this for printing.
|
||||||
match self._dummy {}
|
///
|
||||||
}
|
/// [iso8601]: https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC
|
||||||
}
|
TimezoneOffsetPermissive,
|
||||||
|
|
||||||
impl Eq for InternalFixed {
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for InternalFixed {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "<InternalFixed>")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single formatting item. This is used for both formatting and parsing.
|
/// A single formatting item. This is used for both formatting and parsing.
|
||||||
|
@ -273,6 +257,7 @@ macro_rules! num { ($x:ident) => (Item::Numeric(Numeric::$x, Pad::None)) }
|
||||||
macro_rules! num0 { ($x:ident) => (Item::Numeric(Numeric::$x, Pad::Zero)) }
|
macro_rules! num0 { ($x:ident) => (Item::Numeric(Numeric::$x, Pad::Zero)) }
|
||||||
macro_rules! nums { ($x:ident) => (Item::Numeric(Numeric::$x, Pad::Space)) }
|
macro_rules! nums { ($x:ident) => (Item::Numeric(Numeric::$x, Pad::Space)) }
|
||||||
macro_rules! fix { ($x:ident) => (Item::Fixed(Fixed::$x)) }
|
macro_rules! fix { ($x:ident) => (Item::Fixed(Fixed::$x)) }
|
||||||
|
macro_rules! internal_fix { ($x:ident) => (Item::Fixed(Fixed::Internal(InternalFixed { val: InternalInternal::$x })))}
|
||||||
|
|
||||||
/// An error from the `parse` function.
|
/// An error from the `parse` function.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
|
||||||
|
@ -500,7 +485,7 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
|
||||||
off.map(|&(_, off)| write_local_minus_utc(w, off, false, false)),
|
off.map(|&(_, off)| write_local_minus_utc(w, off, false, false)),
|
||||||
TimezoneOffsetZ =>
|
TimezoneOffsetZ =>
|
||||||
off.map(|&(_, off)| write_local_minus_utc(w, off, true, false)),
|
off.map(|&(_, off)| write_local_minus_utc(w, off, true, false)),
|
||||||
TimezoneOffsetPermissive =>
|
Internal(InternalFixed { val: InternalInternal::TimezoneOffsetPermissive }) =>
|
||||||
panic!("Do not try to write %#z it is undefined"),
|
panic!("Do not try to write %#z it is undefined"),
|
||||||
RFC2822 => // same to `%a, %e %b %Y %H:%M:%S %z`
|
RFC2822 => // same to `%a, %e %b %Y %H:%M:%S %z`
|
||||||
if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) {
|
if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) {
|
||||||
|
@ -522,9 +507,6 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
|
||||||
// for the future expansion
|
|
||||||
Internal(ref int) => match int._dummy {},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match ret {
|
match ret {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::usize;
|
||||||
use Weekday;
|
use Weekday;
|
||||||
|
|
||||||
use super::scan;
|
use super::scan;
|
||||||
use super::{Parsed, ParseResult, Item};
|
use super::{Parsed, ParseResult, Item, InternalFixed, InternalInternal};
|
||||||
use super::{OUT_OF_RANGE, INVALID, TOO_SHORT, TOO_LONG, BAD_FORMAT};
|
use super::{OUT_OF_RANGE, INVALID, TOO_SHORT, TOO_LONG, BAD_FORMAT};
|
||||||
|
|
||||||
fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> ParseResult<()> {
|
fn set_weekday_with_num_days_from_sunday(p: &mut Parsed, v: i64) -> ParseResult<()> {
|
||||||
|
@ -328,7 +328,7 @@ pub fn parse<'a, I>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<(
|
||||||
scan::colon_or_space));
|
scan::colon_or_space));
|
||||||
try!(parsed.set_offset(i64::from(offset)));
|
try!(parsed.set_offset(i64::from(offset)));
|
||||||
}
|
}
|
||||||
TimezoneOffsetPermissive => {
|
Internal(InternalFixed { val: InternalInternal::TimezoneOffsetPermissive }) => {
|
||||||
let offset = try_consume!(scan::timezone_offset_permissive(
|
let offset = try_consume!(scan::timezone_offset_permissive(
|
||||||
s.trim_left(), scan::colon_or_space));
|
s.trim_left(), scan::colon_or_space));
|
||||||
try!(parsed.set_offset(i64::from(offset)));
|
try!(parsed.set_offset(i64::from(offset)));
|
||||||
|
@ -336,9 +336,6 @@ pub fn parse<'a, I>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<(
|
||||||
|
|
||||||
RFC2822 => try_consume!(parse_rfc2822(parsed, s)),
|
RFC2822 => try_consume!(parse_rfc2822(parsed, s)),
|
||||||
RFC3339 => try_consume!(parse_rfc3339(parsed, s)),
|
RFC3339 => try_consume!(parse_rfc3339(parsed, s)),
|
||||||
|
|
||||||
// for the future expansion
|
|
||||||
Internal(ref int) => match int._dummy {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,10 +572,10 @@ fn test_parse() {
|
||||||
check!("zulu", [fix!(TimezoneOffsetZ), lit!("ulu")]; offset: 0);
|
check!("zulu", [fix!(TimezoneOffsetZ), lit!("ulu")]; offset: 0);
|
||||||
check!("+1234ulu", [fix!(TimezoneOffsetZ), lit!("ulu")]; offset: 754 * 60);
|
check!("+1234ulu", [fix!(TimezoneOffsetZ), lit!("ulu")]; offset: 754 * 60);
|
||||||
check!("+12:34ulu", [fix!(TimezoneOffsetZ), lit!("ulu")]; offset: 754 * 60);
|
check!("+12:34ulu", [fix!(TimezoneOffsetZ), lit!("ulu")]; offset: 754 * 60);
|
||||||
check!("Z", [fix!(TimezoneOffsetPermissive)]; offset: 0);
|
check!("Z", [internal_fix!(TimezoneOffsetPermissive)]; offset: 0);
|
||||||
check!("z", [fix!(TimezoneOffsetPermissive)]; offset: 0);
|
check!("z", [internal_fix!(TimezoneOffsetPermissive)]; offset: 0);
|
||||||
check!("+12:00", [fix!(TimezoneOffsetPermissive)]; offset: 12 * 60 * 60);
|
check!("+12:00", [internal_fix!(TimezoneOffsetPermissive)]; offset: 12 * 60 * 60);
|
||||||
check!("+12", [fix!(TimezoneOffsetPermissive)]; offset: 12 * 60 * 60);
|
check!("+12", [internal_fix!(TimezoneOffsetPermissive)]; offset: 12 * 60 * 60);
|
||||||
check!("???", [fix!(TimezoneName)]; BAD_FORMAT); // not allowed
|
check!("???", [fix!(TimezoneName)]; BAD_FORMAT); // not allowed
|
||||||
|
|
||||||
// some practical examples
|
// some practical examples
|
||||||
|
|
|
@ -147,7 +147,7 @@ Notes:
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{Item, Numeric, Fixed, Pad};
|
use super::{Item, Numeric, Fixed, InternalFixed, InternalInternal, Pad};
|
||||||
|
|
||||||
/// Parsing iterator for `strftime`-like format strings.
|
/// Parsing iterator for `strftime`-like format strings.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -270,7 +270,7 @@ impl<'a> Iterator for StrftimeItems<'a> {
|
||||||
num0!(YearMod100)],
|
num0!(YearMod100)],
|
||||||
'y' => num0!(YearMod100),
|
'y' => num0!(YearMod100),
|
||||||
'z' => if is_alternate {
|
'z' => if is_alternate {
|
||||||
fix!(TimezoneOffsetPermissive)
|
internal_fix!(TimezoneOffsetPermissive)
|
||||||
} else {
|
} else {
|
||||||
fix!(TimezoneOffset)
|
fix!(TimezoneOffset)
|
||||||
},
|
},
|
||||||
|
@ -380,7 +380,7 @@ fn test_strftime_items() {
|
||||||
assert_eq!(parse_and_collect("%0e"), [num0!(Day)]);
|
assert_eq!(parse_and_collect("%0e"), [num0!(Day)]);
|
||||||
assert_eq!(parse_and_collect("%_e"), [nums!(Day)]);
|
assert_eq!(parse_and_collect("%_e"), [nums!(Day)]);
|
||||||
assert_eq!(parse_and_collect("%z"), [fix!(TimezoneOffset)]);
|
assert_eq!(parse_and_collect("%z"), [fix!(TimezoneOffset)]);
|
||||||
assert_eq!(parse_and_collect("%#z"), [fix!(TimezoneOffsetPermissive)]);
|
assert_eq!(parse_and_collect("%#z"), [internal_fix!(TimezoneOffsetPermissive)]);
|
||||||
assert_eq!(parse_and_collect("%#m"), [Item::Error]);
|
assert_eq!(parse_and_collect("%#m"), [Item::Error]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue