diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c8b941..9cc0c24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ Chrono obeys the principle of [Semantic Versioning](http://semver.org/). There were/are numerous minor versions before 1.0 due to the language changes. Versions with only mechanical changes will be omitted from the following list. +## next + +### Features + +* Functions that were accepting `Iterator` of `Item`s (for example + `format_with_items`) now accept `Iterator` of `Borrow`, so one can + use values or references. + ## 0.4.9 ### Fixes diff --git a/src/date.rs b/src/date.rs index d449009..7026c41 100644 --- a/src/date.rs +++ b/src/date.rs @@ -3,6 +3,7 @@ //! ISO 8601 calendar date with time zone. +use core::borrow::Borrow; use core::{fmt, hash}; use core::cmp::Ordering; use core::ops::{Add, Sub}; @@ -258,8 +259,8 @@ impl Date where Tz::Offset: fmt::Display { /// Formats the date with the specified formatting items. #[cfg(any(feature = "alloc", feature = "std", test))] #[inline] - pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat - where I: Iterator> + Clone { + pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat + where I: Iterator + Clone, B: Borrow> { DelayedFormat::new_with_offset(Some(self.naive_local()), None, &self.offset, items) } diff --git a/src/datetime.rs b/src/datetime.rs index f0a8c19..e39020d 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -25,6 +25,7 @@ use format::{Item, Numeric, Pad, Fixed}; use format::{parse, Parsed, ParseError, ParseResult, StrftimeItems}; #[cfg(any(feature = "alloc", feature = "std", test))] use format::DelayedFormat; +use core::borrow::Borrow; /// Specific formatting options for seconds. This may be extended in the /// future, so exhaustive matching in external code is not recommended. @@ -326,7 +327,7 @@ impl DateTime { pub fn parse_from_rfc2822(s: &str) -> ParseResult> { const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC2822)]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter().cloned())); + try!(parse(&mut parsed, s, ITEMS.iter())); parsed.to_datetime() } @@ -338,7 +339,7 @@ impl DateTime { pub fn parse_from_rfc3339(s: &str) -> ParseResult> { const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC3339)]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter().cloned())); + try!(parse(&mut parsed, s, ITEMS.iter())); parsed.to_datetime() } @@ -374,14 +375,14 @@ impl DateTime where Tz::Offset: fmt::Display { #[cfg(any(feature = "alloc", feature = "std", test))] pub fn to_rfc2822(&self) -> String { const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC2822)]; - self.format_with_items(ITEMS.iter().cloned()).to_string() + self.format_with_items(ITEMS.iter()).to_string() } /// Returns an RFC 3339 and ISO 8601 date and time string such as `1996-12-19T16:39:57-08:00`. #[cfg(any(feature = "alloc", feature = "std", test))] pub fn to_rfc3339(&self) -> String { const ITEMS: &'static [Item<'static>] = &[Item::Fixed(Fixed::RFC3339)]; - self.format_with_items(ITEMS.iter().cloned()).to_string() + self.format_with_items(ITEMS.iter()).to_string() } /// Return an RFC 3339 and ISO 8601 date and time string with subseconds @@ -450,11 +451,11 @@ impl DateTime where Tz::Offset: fmt::Display { match ssitem { None => self.format_with_items( - PREFIX.iter().chain([tzitem].iter()).cloned() + PREFIX.iter().chain([tzitem].iter()) ).to_string(), Some(s) => self.format_with_items( - PREFIX.iter().chain([s, tzitem].iter()).cloned() + PREFIX.iter().chain([s, tzitem].iter()) ).to_string(), } } @@ -462,8 +463,8 @@ impl DateTime where Tz::Offset: fmt::Display { /// Formats the combined date and time with the specified formatting items. #[cfg(any(feature = "alloc", feature = "std", test))] #[inline] - pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat - where I: Iterator> + Clone { + pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat + where I: Iterator + Clone, B: Borrow> { let local = self.naive_local(); DelayedFormat::new_with_offset(Some(local.date()), Some(local.time()), &self.offset, items) } @@ -638,7 +639,7 @@ impl str::FromStr for DateTime { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter().cloned())); + try!(parse(&mut parsed, s, ITEMS.iter())); parsed.to_datetime() } } diff --git a/src/format/mod.rs b/src/format/mod.rs index b8e6458..e9ae6b9 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -17,6 +17,7 @@ #![allow(ellipsis_inclusive_range_patterns)] +use core::borrow::Borrow; use core::fmt; use core::str::FromStr; #[cfg(any(feature = "std", test))] @@ -356,14 +357,14 @@ const BAD_FORMAT: ParseError = ParseError(ParseErrorKind::BadFormat); /// Tries to format given arguments with given formatting items. /// Internally used by `DelayedFormat`. #[cfg(any(feature = "alloc", feature = "std", test))] -pub fn format<'a, I>( +pub fn format<'a, I, B>( w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Option<&NaiveTime>, off: Option<&(String, FixedOffset)>, items: I, ) -> fmt::Result - where I: Iterator> + where I: Iterator + Clone, B: Borrow> { // full and abbreviated month and weekday names static SHORT_MONTHS: [&'static str; 12] = @@ -380,7 +381,7 @@ pub fn format<'a, I>( let mut result = String::new(); for item in items { - match item { + match item.borrow() { Item::Literal(s) | Item::Space(s) => result.push_str(s), #[cfg(any(feature = "alloc", feature = "std", test))] Item::OwnedLiteral(ref s) | Item::OwnedSpace(ref s) => result.push_str(s), @@ -433,7 +434,7 @@ pub fn format<'a, I>( if let Some(v) = v { try!( - if (spec == Year || spec == IsoYear) && !(0 <= v && v < 10_000) { + if (*spec == Year || *spec == IsoYear) && !(0 <= v && v < 10_000) { // non-four-digit years require an explicit sign as per ISO 8601 match pad { Pad::None => write!(result, "{:+}", v), @@ -633,7 +634,7 @@ pub struct DelayedFormat { } #[cfg(any(feature = "alloc", feature = "std", test))] -impl<'a, I: Iterator> + Clone> DelayedFormat { +impl<'a, I: Iterator + Clone, B: Borrow>> DelayedFormat { /// Makes a new `DelayedFormat` value out of local date and time. pub fn new(date: Option, time: Option, items: I) -> DelayedFormat { DelayedFormat { date: date, time: time, off: None, items: items } @@ -649,7 +650,7 @@ impl<'a, I: Iterator> + Clone> DelayedFormat { } #[cfg(any(feature = "alloc", feature = "std", test))] -impl<'a, I: Iterator> + Clone> fmt::Display for DelayedFormat { +impl<'a, I: Iterator + Clone, B: Borrow>> fmt::Display for DelayedFormat { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { format(f, self.date.as_ref(), self.time.as_ref(), self.off.as_ref(), self.items.clone()) } diff --git a/src/format/parse.rs b/src/format/parse.rs index e8e0d25..ed88722 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -6,6 +6,7 @@ #![allow(deprecated)] +use core::borrow::Borrow; use core::usize; use Weekday; @@ -204,14 +205,14 @@ fn parse_rfc3339<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a st /// so one can prepend any number of whitespace then any number of zeroes before numbers. /// /// - (Still) obeying the intrinsic parsing width. This allows, for example, parsing `HHMMSS`. -pub fn parse<'a, I>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<()> - where I: Iterator> { +pub fn parse<'a, I, B>(parsed: &mut Parsed, mut s: &str, items: I) -> ParseResult<()> + where I: Iterator, B: Borrow> { macro_rules! try_consume { ($e:expr) => ({ let (s_, v) = try!($e); s = s_; v }) } for item in items { - match item { + match item.borrow() { Item::Literal(prefix) => { if s.len() < prefix.len() { return Err(TOO_SHORT); } if !s.starts_with(prefix) { return Err(INVALID); } @@ -388,7 +389,7 @@ fn test_parse() { // workaround for Rust issue #22255 fn parse_all(s: &str, items: &[Item]) -> ParseResult { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, items.iter().cloned())); + try!(parse(&mut parsed, s, items.iter())); Ok(parsed) } @@ -699,12 +700,12 @@ fn test_rfc2822() { fn rfc2822_to_datetime(date: &str) -> ParseResult> { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, date, [Item::Fixed(Fixed::RFC2822)].iter().cloned())); + try!(parse(&mut parsed, date, [Item::Fixed(Fixed::RFC2822)].iter())); parsed.to_datetime() } fn fmt_rfc2822_datetime(dt: DateTime) -> String { - dt.format_with_items([Item::Fixed(Fixed::RFC2822)].iter().cloned()).to_string() + dt.format_with_items([Item::Fixed(Fixed::RFC2822)].iter()).to_string() } // Test against test data above @@ -780,12 +781,12 @@ fn test_rfc3339() { fn rfc3339_to_datetime(date: &str) -> ParseResult> { let mut parsed = Parsed::new(); - try!(parse(&mut parsed, date, [Item::Fixed(Fixed::RFC3339)].iter().cloned())); + try!(parse(&mut parsed, date, [Item::Fixed(Fixed::RFC3339)].iter())); parsed.to_datetime() } fn fmt_rfc3339_datetime(dt: DateTime) -> String { - dt.format_with_items([Item::Fixed(Fixed::RFC3339)].iter().cloned()).to_string() + dt.format_with_items([Item::Fixed(Fixed::RFC3339)].iter()).to_string() } // Test against test data above diff --git a/src/naive/date.rs b/src/naive/date.rs index f67b670..a307604 100644 --- a/src/naive/date.rs +++ b/src/naive/date.rs @@ -3,6 +3,7 @@ //! ISO 8601 calendar date without timezone. +use core::borrow::Borrow; use core::{str, fmt}; use core::ops::{Add, Sub, AddAssign, SubAssign}; use num_traits::ToPrimitive; @@ -920,8 +921,8 @@ impl NaiveDate { /// ~~~~ #[cfg(any(feature = "alloc", feature = "std", test))] #[inline] - pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat - where I: Iterator> + Clone { + pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat + where I: Iterator + Clone, B: Borrow> { DelayedFormat::new(Some(*self), None, items) } @@ -1516,7 +1517,7 @@ impl str::FromStr for NaiveDate { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter().cloned())); + try!(parse(&mut parsed, s, ITEMS.iter())); parsed.to_naive_date() } } diff --git a/src/naive/datetime.rs b/src/naive/datetime.rs index 2049782..feeb9d4 100644 --- a/src/naive/datetime.rs +++ b/src/naive/datetime.rs @@ -3,6 +3,7 @@ //! ISO 8601 date and time without timezone. +use core::borrow::Borrow; use core::{str, fmt, hash}; use core::ops::{Add, Sub, AddAssign, SubAssign}; use num_traits::ToPrimitive; @@ -649,8 +650,8 @@ impl NaiveDateTime { /// ~~~~ #[cfg(any(feature = "alloc", feature = "std", test))] #[inline] - pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat - where I: Iterator> + Clone { + pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat + where I: Iterator + Clone, B: Borrow> { DelayedFormat::new(Some(self.date), Some(self.time), items) } @@ -1487,7 +1488,7 @@ impl str::FromStr for NaiveDateTime { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter().cloned())); + try!(parse(&mut parsed, s, ITEMS.iter())); parsed.to_naive_datetime_with_offset(0) } } diff --git a/src/naive/time.rs b/src/naive/time.rs index c0272c8..9ae72f2 100644 --- a/src/naive/time.rs +++ b/src/naive/time.rs @@ -3,6 +3,7 @@ //! ISO 8601 time without timezone. +use core::borrow::Borrow; use core::{str, fmt, hash}; use core::ops::{Add, Sub, AddAssign, SubAssign}; use oldtime::Duration as OldDuration; @@ -727,8 +728,8 @@ impl NaiveTime { /// ~~~~ #[cfg(any(feature = "alloc", feature = "std", test))] #[inline] - pub fn format_with_items<'a, I>(&self, items: I) -> DelayedFormat - where I: Iterator> + Clone { + pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat + where I: Iterator + Clone, B: Borrow> { DelayedFormat::new(None, Some(*self), items) } @@ -1312,7 +1313,7 @@ impl str::FromStr for NaiveTime { ]; let mut parsed = Parsed::new(); - try!(parse(&mut parsed, s, ITEMS.iter().cloned())); + try!(parse(&mut parsed, s, ITEMS.iter())); parsed.to_naive_time() } }