time/format_description/parse/
mod.rs1use alloc::boxed::Box;
4use alloc::vec::Vec;
5
6pub use self::strftime::{parse_strftime_borrowed, parse_strftime_owned};
7use crate::{error, format_description};
8
9macro_rules! version {
11 ($range:expr) => {
12 $range.contains(&VERSION)
13 };
14}
15
16macro_rules! validate_version {
18 ($version:ident) => {
19 let _ = $crate::format_description::parse::Version::<$version>::IS_VALID;
20 };
21}
22
23mod ast;
24mod format_item;
25mod lexer;
26mod strftime;
27
28struct Version<const N: usize>;
30impl<const N: usize> Version<N> {
31 const IS_VALID: () = assert!(N >= 1 && N <= 2);
34}
35
36pub fn parse(
45 s: &str,
46) -> Result<Vec<format_description::BorrowedFormatItem<'_>>, error::InvalidFormatDescription> {
47 parse_borrowed::<1>(s)
48}
49
50pub fn parse_borrowed<const VERSION: usize>(
56 s: &str,
57) -> Result<Vec<format_description::BorrowedFormatItem<'_>>, error::InvalidFormatDescription> {
58 validate_version!(VERSION);
59 let mut lexed = lexer::lex::<VERSION>(s.as_bytes());
60 let ast = ast::parse::<_, VERSION>(&mut lexed);
61 let format_items = format_item::parse(ast);
62 Ok(format_items
63 .map(|res| res.and_then(TryInto::try_into))
64 .collect::<Result<_, _>>()?)
65}
66
67pub fn parse_owned<const VERSION: usize>(
78 s: &str,
79) -> Result<format_description::OwnedFormatItem, error::InvalidFormatDescription> {
80 validate_version!(VERSION);
81 let mut lexed = lexer::lex::<VERSION>(s.as_bytes());
82 let ast = ast::parse::<_, VERSION>(&mut lexed);
83 let format_items = format_item::parse(ast);
84 let items = format_items.collect::<Result<Box<_>, _>>()?;
85 Ok(items.into())
86}
87
88fn attach_location<'item>(
90 iter: impl Iterator<Item = &'item u8>,
91) -> impl Iterator<Item = (&'item u8, Location)> {
92 let mut byte_pos = 0;
93
94 iter.map(move |byte| {
95 let location = Location { byte: byte_pos };
96 byte_pos += 1;
97 (byte, location)
98 })
99}
100
101#[derive(Clone, Copy)]
103struct Location {
104 byte: u32,
106}
107
108impl Location {
109 const fn to(self, end: Self) -> Span {
111 Span { start: self, end }
112 }
113
114 const fn to_self(self) -> Span {
116 Span {
117 start: self,
118 end: self,
119 }
120 }
121
122 #[must_use = "this does not modify the original value"]
126 const fn offset(&self, offset: u32) -> Self {
127 Self {
128 byte: self.byte + offset,
129 }
130 }
131
132 const fn error(self, message: &'static str) -> ErrorInner {
134 ErrorInner {
135 _message: message,
136 _span: Span {
137 start: self,
138 end: self,
139 },
140 }
141 }
142}
143
144#[derive(Clone, Copy)]
146struct Span {
147 start: Location,
148 end: Location,
149}
150
151impl Span {
152 #[must_use = "this does not modify the original value"]
154 const fn shrink_to_start(&self) -> Self {
155 Self {
156 start: self.start,
157 end: self.start,
158 }
159 }
160
161 #[must_use = "this does not modify the original value"]
163 const fn shrink_to_end(&self) -> Self {
164 Self {
165 start: self.end,
166 end: self.end,
167 }
168 }
169
170 #[must_use = "this does not modify the original value"]
172 const fn shrink_to_before(&self, pos: u32) -> Self {
173 Self {
174 start: self.start,
175 end: Location {
176 byte: self.start.byte + pos - 1,
177 },
178 }
179 }
180
181 #[must_use = "this does not modify the original value"]
183 const fn shrink_to_after(&self, pos: u32) -> Self {
184 Self {
185 start: Location {
186 byte: self.start.byte + pos + 1,
187 },
188 end: self.end,
189 }
190 }
191
192 const fn error(self, message: &'static str) -> ErrorInner {
194 ErrorInner {
195 _message: message,
196 _span: self,
197 }
198 }
199}
200
201#[derive(Clone, Copy)]
203struct Spanned<T> {
204 value: T,
206 span: Span,
208}
209
210impl<T> core::ops::Deref for Spanned<T> {
211 type Target = T;
212
213 fn deref(&self) -> &Self::Target {
214 &self.value
215 }
216}
217
218trait SpannedValue: Sized {
220 fn spanned(self, span: Span) -> Spanned<Self>;
222}
223
224impl<T> SpannedValue for T {
225 fn spanned(self, span: Span) -> Spanned<Self> {
226 Spanned { value: self, span }
227 }
228}
229
230struct ErrorInner {
232 _message: &'static str,
234 _span: Span,
236}
237
238struct Error {
240 _inner: Unused<ErrorInner>,
242 public: error::InvalidFormatDescription,
244}
245
246impl From<Error> for error::InvalidFormatDescription {
247 fn from(error: Error) -> Self {
248 error.public
249 }
250}
251
252struct Unused<T>(core::marker::PhantomData<T>);
258
259fn unused<T>(_: T) -> Unused<T> {
261 Unused(core::marker::PhantomData)
262}