Skip to content

Commit

Permalink
Add StrftimeItems::parse_to_owned
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Sep 21, 2023
1 parent c2e9d70 commit 9b2325f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,22 @@ const fn internal_fixed(val: InternalInternal) -> Item<'static> {
Item::Fixed(Fixed::Internal(InternalFixed { val }))
}

impl<'a> Item<'a> {
/// Convert items that contain a reference to the format string into an owned variant.
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn to_owned(self) -> Item<'static> {
match self {
Item::Literal(s) => Item::OwnedLiteral(Box::from(s)),
Item::Space(s) => Item::OwnedSpace(Box::from(s)),
Item::Numeric(n, p) => Item::Numeric(n, p),
Item::Fixed(f) => Item::Fixed(f),
Item::OwnedLiteral(l) => Item::OwnedLiteral(l),
Item::OwnedSpace(s) => Item::OwnedSpace(s),
Item::Error => Item::Error,

Check warning on line 386 in src/format/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/format/mod.rs#L384-L386

Added lines #L384 - L386 were not covered by tests
}
}
}

/// An error from the `parse` function.
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
pub struct ParseError(ParseErrorKind);
Expand Down
42 changes: 42 additions & 0 deletions src/format/strftime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,48 @@ impl<'a> StrftimeItems<'a> {
}
Ok(result)
}

/// Parse format string into a `Vec` of [`Item`]'s that contain no references to slices of the
/// format string.
///
/// A `Vec` created with [`StrftimeItems::parse`] contains references to the format string,
/// binding the lifetime of the `Vec` to that string. [`StrftimeItems::parse_to_owned`] will
/// convert the references to owned types.
///
/// # Errors
///
/// Returns an error if the format string contains an invalid or unrecognised formatting
/// specifier.
///
/// # Example
///
/// ```
/// use chrono::format::{Item, ParseError, StrftimeItems};
/// use chrono::NaiveDate;
///
/// fn format_items(date_fmt: &str, time_fmt: &str) -> Result<Vec<Item<'static>>, ParseError> {
/// // `fmt_string` is dropped at the end of this function.
/// let fmt_string = format!("{} {}", date_fmt, time_fmt);
/// StrftimeItems::new(&fmt_string).parse_to_owned()
/// }
///
/// let fmt_items = format_items("%e %b %Y", "%k.%M")?;
/// let datetime = NaiveDate::from_ymd_opt(2023, 7, 11).unwrap().and_hms_opt(9, 0, 0).unwrap();
///
/// assert_eq!(
/// datetime.format_with_items(fmt_items.as_slice().iter()).to_string(),
/// "11 Jul 2023 9.00"
/// );
/// # Ok::<(), ParseError>(())
/// ```
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn parse_to_owned(self) -> Result<Vec<Item<'static>>, ParseError> {
let result: Vec<_> = self.map(|i| i.to_owned()).collect();
if result.iter().any(|i| i == &Item::Error) {
return Err(BAD_FORMAT);

Check warning on line 379 in src/format/strftime.rs

View check run for this annotation

Codecov / codecov/patch

src/format/strftime.rs#L379

Added line #L379 was not covered by tests
}
Ok(result)
}
}

const HAVE_ALTERNATES: &str = "z";
Expand Down

0 comments on commit 9b2325f

Please sign in to comment.