Skip to content

Commit 58a2149

Browse files
committed
Add StrftimeItems::parse_to_owned
1 parent 59eeb8c commit 58a2149

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/format/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,22 @@ const fn internal_fixed(val: InternalInternal) -> Item<'static> {
363363
Item::Fixed(Fixed::Internal(InternalFixed { val }))
364364
}
365365

366+
impl<'a> Item<'a> {
367+
/// Convert items that contain a reference to the format string into an owned variant.
368+
#[cfg(any(feature = "alloc", feature = "std"))]
369+
pub fn to_owned(self) -> Item<'static> {
370+
match self {
371+
Item::Literal(s) => Item::OwnedLiteral(Box::from(s)),
372+
Item::Space(s) => Item::OwnedSpace(Box::from(s)),
373+
Item::Numeric(n, p) => Item::Numeric(n, p),
374+
Item::Fixed(f) => Item::Fixed(f),
375+
Item::OwnedLiteral(l) => Item::OwnedLiteral(l),
376+
Item::OwnedSpace(s) => Item::OwnedSpace(s),
377+
Item::Error => Item::Error,
378+
}
379+
}
380+
}
381+
366382
/// An error from the `parse` function.
367383
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
368384
pub struct ParseError(ParseErrorKind);

src/format/strftime.rs

+43
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,49 @@ impl<'a> StrftimeItems<'a> {
338338
})
339339
.collect()
340340
}
341+
342+
/// Parse format string into a `Vec` of [`Item`]'s that contain no references to slices of the
343+
/// format string.
344+
///
345+
/// A `Vec` created with [`StrftimeItems::parse`] contains references to the format string,
346+
/// binding the lifetime of the `Vec` to that string. [`StrftimeItems::parse_to_owned`] will
347+
/// convert the references to owned types.
348+
///
349+
/// # Errors
350+
///
351+
/// Returns an error if the format string contains an invalid or unrecognized formatting
352+
/// specifier.
353+
///
354+
/// # Example
355+
///
356+
/// ```
357+
/// use chrono::format::{Item, ParseError, StrftimeItems};
358+
/// use chrono::NaiveDate;
359+
///
360+
/// fn format_items(date_fmt: &str, time_fmt: &str) -> Result<Vec<Item<'static>>, ParseError> {
361+
/// // `fmt_string` is dropped at the end of this function.
362+
/// let fmt_string = format!("{} {}", date_fmt, time_fmt);
363+
/// StrftimeItems::new(&fmt_string).parse_to_owned()
364+
/// }
365+
///
366+
/// let fmt_items = format_items("%e %b %Y", "%k.%M")?;
367+
/// let datetime = NaiveDate::from_ymd_opt(2023, 7, 11).unwrap().and_hms_opt(9, 0, 0).unwrap();
368+
///
369+
/// assert_eq!(
370+
/// datetime.format_with_items(fmt_items.as_slice().iter()).to_string(),
371+
/// "11 Jul 2023 9.00"
372+
/// );
373+
/// # Ok::<(), ParseError>(())
374+
/// ```
375+
#[cfg(any(feature = "alloc", feature = "std"))]
376+
pub fn parse_to_owned(self) -> Result<Vec<Item<'static>>, ParseError> {
377+
self.into_iter()
378+
.map(|item| match item == Item::Error {
379+
false => Ok(item.to_owned()),
380+
true => Err(BAD_FORMAT),
381+
})
382+
.collect()
383+
}
341384
}
342385

343386
const HAVE_ALTERNATES: &str = "z";

0 commit comments

Comments
 (0)