1 //! AST for parsing format descriptions.
3 use alloc
::string
::String
;
6 use core
::iter
::Peekable
;
8 use super::{lexer, Error, Location, Span}
;
10 /// One part of a complete format description.
11 #[allow(variant_size_differences)]
12 pub(super) enum Item
<'a
> {
13 /// A literal string, formatted and parsed as-is.
15 /// The string itself.
17 /// Where the string originates from in the format string.
20 /// A sequence of brackets. The first acts as the escape character.
22 /// The first bracket.
24 /// The second bracket.
27 /// Part of a type, along with its modifiers.
29 /// Where the opening bracket was in the format string.
30 _opening_bracket
: Location
,
31 /// Whitespace between the opening bracket and name.
32 _leading_whitespace
: Option
<Whitespace
<'a
>>,
33 /// The name of the component.
35 /// The modifiers for the component.
36 modifiers
: Vec
<Modifier
<'a
>>,
37 /// Whitespace between the modifiers and closing bracket.
38 _trailing_whitespace
: Option
<Whitespace
<'a
>>,
39 /// Where the closing bracket was in the format string.
40 _closing_bracket
: Location
,
44 /// Whitespace within a component.
45 pub(super) struct Whitespace
<'a
> {
46 /// The whitespace itself.
47 pub(super) _value
: &'a
[u8],
48 /// Where the whitespace was in the format string.
49 pub(super) span
: Span
,
52 /// The name of a component.
53 pub(super) struct Name
<'a
> {
55 pub(super) value
: &'a
[u8],
56 /// Where the name was in the format string.
57 pub(super) span
: Span
,
60 /// A modifier for a component.
61 pub(super) struct Modifier
<'a
> {
62 /// Whitespace preceding the modifier.
63 pub(super) _leading_whitespace
: Whitespace
<'a
>,
64 /// The key of the modifier.
65 pub(super) key
: Key
<'a
>,
66 /// Where the colon of the modifier was in the format string.
67 pub(super) _colon
: Location
,
68 /// The value of the modifier.
69 pub(super) value
: Value
<'a
>,
72 /// The key of a modifier.
73 pub(super) struct Key
<'a
> {
75 pub(super) value
: &'a
[u8],
76 /// Where the key was in the format string.
77 pub(super) span
: Span
,
80 /// The value of a modifier.
81 pub(super) struct Value
<'a
> {
83 pub(super) value
: &'a
[u8],
84 /// Where the value was in the format string.
85 pub(super) span
: Span
,
88 /// Parse the provided tokens into an AST.
89 pub(super) fn parse
<'a
>(
90 tokens
: impl Iterator
<Item
= lexer
::Token
<'a
>>,
91 ) -> impl Iterator
<Item
= Result
<Item
<'a
>, Error
>> {
92 let mut tokens
= tokens
.peekable();
93 iter
::from_fn(move || {
94 Some(match tokens
.next()?
{
95 lexer
::Token
::Literal { value, span }
=> Ok(Item
::Literal { value, _span: span }
),
96 lexer
::Token
::Bracket
{
97 kind
: lexer
::BracketKind
::Opening
,
101 if let Some(&lexer
::Token
::Bracket
{
102 kind
: lexer
::BracketKind
::Opening
,
103 location
: second_location
,
106 tokens
.next(); // consume
107 Ok(Item
::EscapedBracket
{
109 _second
: second_location
,
114 parse_component(location
, &mut tokens
)
117 lexer
::Token
::Bracket
{
118 kind
: lexer
::BracketKind
::Closing
,
121 "internal error: closing bracket should have been consumed by `parse_component`",
123 lexer
::Token
::ComponentPart
{
128 "internal error: component part should have been consumed by `parse_component`",
134 /// Parse a component. This assumes that the opening bracket has already been consumed.
135 fn parse_component
<'a
>(
136 opening_bracket
: Location
,
137 tokens
: &mut Peekable
<impl Iterator
<Item
= lexer
::Token
<'a
>>>,
138 ) -> Result
<Item
<'a
>, Error
> {
139 let leading_whitespace
= if let Some(&lexer
::Token
::ComponentPart
{
140 kind
: lexer
::ComponentKind
::Whitespace
,
145 tokens
.next(); // consume
154 let name
= if let Some(&lexer
::Token
::ComponentPart
{
155 kind
: lexer
::ComponentKind
::NotWhitespace
,
160 tokens
.next(); // consume
163 let span
= leading_whitespace
.map_or_else(
165 start
: opening_bracket
,
166 end
: opening_bracket
,
168 |whitespace
| whitespace
.span
.shrink_to_end(),
171 _inner
: span
.error("expected component name"),
172 public
: crate::error
::InvalidFormatDescription
::MissingComponentName
{
173 index
: span
.start_byte(),
178 let mut modifiers
= Vec
::new();
179 let trailing_whitespace
= loop {
180 let whitespace
= if let Some(&lexer
::Token
::ComponentPart
{
181 kind
: lexer
::ComponentKind
::Whitespace
,
186 tokens
.next(); // consume
195 if let Some(&lexer
::Token
::ComponentPart
{
196 kind
: lexer
::ComponentKind
::NotWhitespace
,
201 tokens
.next(); // consume
203 let colon_index
= match value
.iter().position(|&b
| b
== b'
:'
) {
204 Some(index
) => index
,
207 _inner
: span
.error("modifier must be of the form `key:value`"),
208 public
: crate::error
::InvalidFormatDescription
::InvalidModifier
{
209 value
: String
::from_utf8_lossy(value
).into_owned(),
210 index
: span
.start_byte(),
215 let key
= &value
[..colon_index
];
216 let value
= &value
[colon_index
+ 1..];
220 _inner
: span
.shrink_to_start().error("expected modifier key"),
221 public
: crate::error
::InvalidFormatDescription
::InvalidModifier
{
222 value
: String
::new(),
223 index
: span
.start_byte(),
227 if value
.is_empty() {
229 _inner
: span
.shrink_to_end().error("expected modifier value"),
230 public
: crate::error
::InvalidFormatDescription
::InvalidModifier
{
231 value
: String
::new(),
232 index
: span
.shrink_to_end().start_byte(),
237 modifiers
.push(Modifier
{
238 _leading_whitespace
: whitespace
,
241 span
: span
.subspan(..colon_index
),
243 _colon
: span
.start
.offset(colon_index
),
246 span
: span
.subspan(colon_index
+ 1..),
250 break Some(whitespace
);
254 let closing_bracket
= if let Some(&lexer
::Token
::Bracket
{
255 kind
: lexer
::BracketKind
::Closing
,
259 tokens
.next(); // consume
263 _inner
: opening_bracket
.error("unclosed bracket"),
264 public
: crate::error
::InvalidFormatDescription
::UnclosedOpeningBracket
{
265 index
: opening_bracket
.byte
,
271 _opening_bracket
: opening_bracket
,
272 _leading_whitespace
: leading_whitespace
,
275 _trailing_whitespace
: trailing_whitespace
,
276 _closing_bracket
: closing_bracket
,