Skip to main content

time_macros/format_description/
mod.rs

1//! Parser for format descriptions.
2
3use 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}