time_macros/format_description/
mod.rs1use crate::FormatDescriptionVersion;
4
5mod ast;
6mod format_item;
7mod lexer;
8pub(crate) mod public;
9
10pub(crate) fn parse_with_version(
11 version: FormatDescriptionVersion,
12 s: &[u8],
13 proc_span: proc_macro::Span,
14) -> Result<public::OwnedFormatItem, crate::Error> {
15 let mut lexed = lexer::lex(version, s, proc_span);
16 let ast = ast::parse(version, &mut lexed);
17 let format_items = format_item::parse(ast)
18 .map(|res| res.and_then(|item| (version, item).try_into()))
19 .collect::<Result<_, _>>()?;
20
21 let mut fd = public::OwnedFormatItem {
22 version,
23 inner: public::OwnedFormatItemInner::Compound(format_items),
24 };
25 fd.optimize();
26
27 let top_level_item = if let public::OwnedFormatItemInner::Compound(items) = &mut fd.inner
28 && items.len() == 1
29 && let Some(item) = items.pop()
30 {
31 public::OwnedFormatItem {
32 version,
33 inner: item,
34 }
35 } else {
36 fd
37 };
38
39 Ok(top_level_item)
40}
41
42#[derive(Debug, Clone, Copy)]
43struct Location {
44 byte: u32,
45 proc_span: proc_macro::Span,
46}
47
48impl Location {
49 fn to(self, end: Self) -> Span {
50 Span { start: self, end }
51 }
52
53 #[must_use = "this does not modify the original value"]
54 fn offset(&self, offset: u32) -> Self {
55 Self {
56 byte: self.byte + offset,
57 proc_span: self.proc_span,
58 }
59 }
60
61 fn error(self, message: &'static str) -> Error {
62 Error {
63 message,
64 _span: unused(Span {
65 start: self,
66 end: self,
67 }),
68 proc_span: self.proc_span,
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy)]
74struct Span {
75 start: Location,
76 end: Location,
77}
78
79impl Span {
80 fn dummy() -> Self {
81 Self {
82 start: Location {
83 byte: u32::MAX,
84 proc_span: proc_macro::Span::call_site(),
85 },
86 end: Location {
87 byte: u32::MAX,
88 proc_span: proc_macro::Span::call_site(),
89 },
90 }
91 }
92
93 #[must_use = "this does not modify the original value"]
94 const fn shrink_to_start(&self) -> Self {
95 Self {
96 start: self.start,
97 end: self.start,
98 }
99 }
100
101 #[must_use = "this does not modify the original value"]
102 const fn shrink_to_end(&self) -> Self {
103 Self {
104 start: self.end,
105 end: self.end,
106 }
107 }
108
109 fn error(self, message: &'static str) -> Error {
110 Error {
111 message,
112 _span: unused(self),
113 proc_span: self.start.proc_span,
114 }
115 }
116}
117
118#[derive(Debug, Clone, Copy)]
119struct Spanned<T> {
120 value: T,
121 span: Span,
122}
123
124impl<T> core::ops::Deref for Spanned<T> {
125 type Target = T;
126
127 fn deref(&self) -> &Self::Target {
128 &self.value
129 }
130}
131
132impl<T> Spanned<T> {
133 #[inline]
134 fn map<F, U>(self, f: F) -> Spanned<U>
135 where
136 F: FnOnce(T) -> U,
137 {
138 Spanned {
139 value: f(self.value),
140 span: self.span,
141 }
142 }
143}
144
145trait OptionExt<T> {
146 fn transpose(self) -> Spanned<Option<T>>;
147}
148
149impl<T> OptionExt<T> for Option<Spanned<T>> {
150 #[inline]
151 fn transpose(self) -> Spanned<Option<T>> {
152 match self {
153 Some(spanned) => Spanned {
154 value: Some(spanned.value),
155 span: spanned.span,
156 },
157 None => Spanned {
158 value: None,
159 span: Span::dummy(),
160 },
161 }
162 }
163}
164
165trait SpannedValue: Sized {
166 fn spanned(self, span: Span) -> Spanned<Self>;
167}
168
169impl<T> SpannedValue for T {
170 fn spanned(self, span: Span) -> Spanned<Self> {
171 Spanned { value: self, span }
172 }
173}
174
175#[derive(Debug)]
176struct Error {
177 message: &'static str,
178 _span: Unused<Span>,
179 proc_span: proc_macro::Span,
180}
181
182impl From<Error> for crate::Error {
183 fn from(error: Error) -> Self {
184 Self::Custom {
185 message: error.message.into(),
186 span_start: Some(error.proc_span),
187 span_end: Some(error.proc_span),
188 }
189 }
190}
191
192struct Unused<T>(core::marker::PhantomData<T>);
193
194impl<T> core::fmt::Debug for Unused<T> {
195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196 f.debug_tuple("Unused").finish()
197 }
198}
199
200fn unused<T>(_: T) -> Unused<T> {
201 Unused(core::marker::PhantomData)
202}