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