//! A format item with borrowed data. #[cfg(feature = "alloc")] use alloc::string::String; #[cfg(feature = "alloc")] use core::fmt; use crate::error; use crate::format_description::Component; /// A complete description of how to format and parse a type. #[non_exhaustive] #[cfg_attr(not(feature = "alloc"), derive(Debug))] #[derive(Clone, PartialEq, Eq)] pub enum BorrowedFormatItem<'a> { /// Bytes that are formatted as-is. /// /// **Note**: If you call the `format` method that returns a `String`, these bytes will be /// passed through `String::from_utf8_lossy`. Literal(&'a [u8]), /// A minimal representation of a single non-literal item. Component(Component), /// A series of literals or components that collectively form a partial or complete /// description. Compound(&'a [Self]), /// A `FormatItem` that may or may not be present when parsing. If parsing fails, there /// will be no effect on the resulting `struct`. /// /// This variant has no effect on formatting, as the value is guaranteed to be present. Optional(&'a Self), /// A series of `FormatItem`s where, when parsing, the first successful parse is used. When /// formatting, the first element of the slice is used. An empty slice is a no-op when /// formatting or parsing. First(&'a [Self]), } #[cfg(feature = "alloc")] impl fmt::Debug for BorrowedFormatItem<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Literal(literal) => f.write_str(&String::from_utf8_lossy(literal)), Self::Component(component) => component.fmt(f), Self::Compound(compound) => compound.fmt(f), Self::Optional(item) => f.debug_tuple("Optional").field(item).finish(), Self::First(items) => f.debug_tuple("First").field(items).finish(), } } } impl From for BorrowedFormatItem<'_> { fn from(component: Component) -> Self { Self::Component(component) } } impl TryFrom> for Component { type Error = error::DifferentVariant; fn try_from(value: BorrowedFormatItem<'_>) -> Result { match value { BorrowedFormatItem::Component(component) => Ok(component), _ => Err(error::DifferentVariant), } } } impl<'a> From<&'a [BorrowedFormatItem<'_>]> for BorrowedFormatItem<'a> { fn from(items: &'a [BorrowedFormatItem<'_>]) -> Self { Self::Compound(items) } } impl<'a> TryFrom> for &[BorrowedFormatItem<'a>] { type Error = error::DifferentVariant; fn try_from(value: BorrowedFormatItem<'a>) -> Result { match value { BorrowedFormatItem::Compound(items) => Ok(items), _ => Err(error::DifferentVariant), } } } impl PartialEq for BorrowedFormatItem<'_> { fn eq(&self, rhs: &Component) -> bool { matches!(self, Self::Component(component) if component == rhs) } } impl PartialEq> for Component { fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool { rhs == self } } impl PartialEq<&[Self]> for BorrowedFormatItem<'_> { fn eq(&self, rhs: &&[Self]) -> bool { matches!(self, Self::Compound(compound) if compound == rhs) } } impl PartialEq> for &[BorrowedFormatItem<'_>] { fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool { rhs == self } }