]> git.proxmox.com Git - rustc.git/blob - vendor/time/src/format_description/owned_format_item.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / vendor / time / src / format_description / owned_format_item.rs
1 //! A format item with owned data.
2
3 use alloc::boxed::Box;
4 use alloc::string::String;
5 use alloc::vec::Vec;
6 use core::fmt;
7
8 use crate::error;
9 use crate::format_description::{Component, FormatItem};
10
11 /// A complete description of how to format and parse a type.
12 #[non_exhaustive]
13 #[derive(Clone, PartialEq, Eq)]
14 pub enum OwnedFormatItem {
15 /// Bytes that are formatted as-is.
16 ///
17 /// **Note**: If you call the `format` method that returns a `String`, these bytes will be
18 /// passed through `String::from_utf8_lossy`.
19 Literal(Box<[u8]>),
20 /// A minimal representation of a single non-literal item.
21 Component(Component),
22 /// A series of literals or components that collectively form a partial or complete
23 /// description.
24 Compound(Box<[Self]>),
25 /// A `FormatItem` that may or may not be present when parsing. If parsing fails, there
26 /// will be no effect on the resulting `struct`.
27 ///
28 /// This variant has no effect on formatting, as the value is guaranteed to be present.
29 Optional(Box<Self>),
30 /// A series of `FormatItem`s where, when parsing, the first successful parse is used. When
31 /// formatting, the first element of the [`Vec`] is used. An empty [`Vec`] is a no-op when
32 /// formatting or parsing.
33 First(Box<[Self]>),
34 }
35
36 impl fmt::Debug for OwnedFormatItem {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 Self::Literal(literal) => f.write_str(&String::from_utf8_lossy(literal)),
40 Self::Component(component) => component.fmt(f),
41 Self::Compound(compound) => compound.fmt(f),
42 Self::Optional(item) => f.debug_tuple("Optional").field(item).finish(),
43 Self::First(items) => f.debug_tuple("First").field(items).finish(),
44 }
45 }
46 }
47
48 // region: conversions from FormatItem
49 impl From<FormatItem<'_>> for OwnedFormatItem {
50 fn from(item: FormatItem<'_>) -> Self {
51 (&item).into()
52 }
53 }
54
55 impl From<&FormatItem<'_>> for OwnedFormatItem {
56 fn from(item: &FormatItem<'_>) -> Self {
57 match item {
58 FormatItem::Literal(literal) => Self::Literal(literal.to_vec().into_boxed_slice()),
59 FormatItem::Component(component) => Self::Component(*component),
60 FormatItem::Compound(compound) => Self::Compound(
61 compound
62 .iter()
63 .cloned()
64 .map(Into::into)
65 .collect::<Vec<_>>()
66 .into_boxed_slice(),
67 ),
68 FormatItem::Optional(item) => Self::Optional(Box::new((*item).into())),
69 FormatItem::First(items) => Self::First(
70 items
71 .iter()
72 .cloned()
73 .map(Into::into)
74 .collect::<Vec<_>>()
75 .into_boxed_slice(),
76 ),
77 }
78 }
79 }
80
81 impl From<Vec<FormatItem<'_>>> for OwnedFormatItem {
82 fn from(items: Vec<FormatItem<'_>>) -> Self {
83 items.as_slice().into()
84 }
85 }
86
87 impl<'a, T: AsRef<[FormatItem<'a>]> + ?Sized> From<&T> for OwnedFormatItem {
88 fn from(items: &T) -> Self {
89 Self::Compound(
90 items
91 .as_ref()
92 .iter()
93 .cloned()
94 .map(Into::into)
95 .collect::<Vec<_>>()
96 .into_boxed_slice(),
97 )
98 }
99 }
100 // endregion conversions from FormatItem
101
102 // region: from variants
103 impl From<Component> for OwnedFormatItem {
104 fn from(component: Component) -> Self {
105 Self::Component(component)
106 }
107 }
108
109 impl TryFrom<OwnedFormatItem> for Component {
110 type Error = error::DifferentVariant;
111
112 fn try_from(value: OwnedFormatItem) -> Result<Self, Self::Error> {
113 match value {
114 OwnedFormatItem::Component(component) => Ok(component),
115 _ => Err(error::DifferentVariant),
116 }
117 }
118 }
119
120 impl From<Vec<Self>> for OwnedFormatItem {
121 fn from(items: Vec<Self>) -> Self {
122 Self::Compound(items.into_boxed_slice())
123 }
124 }
125
126 impl TryFrom<OwnedFormatItem> for Vec<OwnedFormatItem> {
127 type Error = error::DifferentVariant;
128
129 fn try_from(value: OwnedFormatItem) -> Result<Self, Self::Error> {
130 match value {
131 OwnedFormatItem::Compound(items) => Ok(items.into_vec()),
132 _ => Err(error::DifferentVariant),
133 }
134 }
135 }
136 // endregion from variants
137
138 // region: equality
139 impl PartialEq<Component> for OwnedFormatItem {
140 fn eq(&self, rhs: &Component) -> bool {
141 matches!(self, Self::Component(component) if component == rhs)
142 }
143 }
144
145 impl PartialEq<OwnedFormatItem> for Component {
146 fn eq(&self, rhs: &OwnedFormatItem) -> bool {
147 rhs == self
148 }
149 }
150
151 impl PartialEq<&[Self]> for OwnedFormatItem {
152 fn eq(&self, rhs: &&[Self]) -> bool {
153 matches!(self, Self::Compound(compound) if &&**compound == rhs)
154 }
155 }
156
157 impl PartialEq<OwnedFormatItem> for &[OwnedFormatItem] {
158 fn eq(&self, rhs: &OwnedFormatItem) -> bool {
159 rhs == self
160 }
161 }
162 // endregion equality