1
use alloc::borrow::Cow;
2
use alloc::vec::Vec;
3
use core::fmt::{Display, Formatter};
4
use core::mem;
5
use core::ops::{Deref, Range};
6

            
7
use crate::tokenizer::{self, Balanced, Integer, Token, TokenKind, Tokenizer};
8

            
9
/// Parses input as a sequence of [`Event`]s.
10
#[derive(Debug)]
11
pub struct Parser<'s> {
12
    tokens: Tokenizer<'s, false>,
13
    peeked: Option<Result<Token<'s>, tokenizer::Error>>,
14
    nested: Vec<(usize, NestedState)>,
15
    root_state: State<'s>,
16
    config: Config,
17
}
18

            
19
impl<'s> Parser<'s> {
20
    /// Returns a parser that parses `source` using `configuration`.
21
    #[must_use]
22
53
    pub fn new(source: &'s str, configuration: Config) -> Self {
23
53
        Self {
24
53
            tokens: Tokenizer::minified(source),
25
53
            peeked: None,
26
53
            nested: Vec::new(),
27
53
            root_state: State::AtStart,
28
53
            config: configuration,
29
53
        }
30
53
    }
31

            
32
    /// Validates that `source` would parse successfully using `configuration`.
33
    #[must_use]
34
    pub fn validate(source: &'s str, configuration: Config) -> bool {
35
        Self::new(source, configuration).all(|result| result.is_ok())
36
    }
37

            
38
    /// Returns the current byte offset of the parser.
39
    #[must_use]
40
1352
    pub const fn current_offset(&self) -> usize {
41
1352
        self.tokens.current_offset()
42
1352
    }
43

            
44
    /// Returns the range between the start of the containing nested event and
45
    /// the current byte offset of the parser.
46
    #[must_use]
47
6
    pub fn current_range(&self) -> Range<usize> {
48
6
        let start = self.nested.last().map_or(0, |(offset, _)| *offset);
49
6
        start..self.tokens.current_offset()
50
6
    }
51

            
52
600
    fn peek(&mut self) -> Option<&Token<'s>> {
53
600
        if self.peeked.is_none() {
54
322
            self.peeked = self.tokens.next();
55
322
        }
56

            
57
600
        self.peeked.as_ref().and_then(|r| r.as_ref().ok())
58
600
    }
59

            
60
1378
    fn next_token(&mut self) -> Option<Result<Token<'s>, tokenizer::Error>> {
61
1378
        self.peeked.take().or_else(|| self.tokens.next())
62
1378
    }
63

            
64
581
    fn next_token_parts(
65
581
        &mut self,
66
581
    ) -> Result<(Range<usize>, Option<TokenKind<'s>>), tokenizer::Error> {
67
581
        Ok(match self.next_token().transpose()? {
68
581
            Some(token) => (token.location, Some(token.kind)),
69
            None => (
70
                self.tokens.current_offset()..self.tokens.current_offset(),
71
                None,
72
            ),
73
        })
74
581
    }
75

            
76
89
    fn next_or_eof(&mut self) -> Result<Token<'s>, Error> {
77
89
        match self.next_token() {
78
89
            Some(Ok(token)) => Ok(token),
79
            Some(Err(err)) => Err(err.into()),
80
            None => Err(Error::new(
81
                self.tokens.current_offset()..self.tokens.current_offset(),
82
                ErrorKind::UnexpectedEof,
83
            )),
84
        }
85
89
    }
86

            
87
691
    fn parse_token(
88
691
        &mut self,
89
691
        token: Token<'s>,
90
691
        allowed_close: Option<Balanced>,
91
691
    ) -> Result<Event<'s>, Error> {
92
36
        match token.kind {
93
228
            TokenKind::Integer(integer) => Ok(Event::new(
94
228
                token.location,
95
228
                EventKind::Primitive(Primitive::Integer(integer)),
96
228
            )),
97
6
            TokenKind::Float(float) => Ok(Event::new(
98
6
                token.location,
99
6
                EventKind::Primitive(Primitive::Float(float)),
100
6
            )),
101
24
            TokenKind::Bool(value) => Ok(Event::new(
102
24
                token.location,
103
24
                EventKind::Primitive(Primitive::Bool(value)),
104
24
            )),
105
16
            TokenKind::Character(value) => Ok(Event::new(
106
16
                token.location,
107
16
                EventKind::Primitive(Primitive::Char(value)),
108
16
            )),
109
4
            TokenKind::Byte(value) => Ok(Event::new(
110
4
                token.location,
111
4
                EventKind::Primitive(Primitive::Integer(Integer::Usize(value as usize))),
112
4
            )),
113
33
            TokenKind::String(value) => Ok(Event::new(
114
33
                token.location,
115
33
                EventKind::Primitive(Primitive::String(value)),
116
33
            )),
117
16
            TokenKind::Bytes(value) => Ok(Event::new(
118
16
                token.location,
119
16
                EventKind::Primitive(Primitive::Bytes(value)),
120
16
            )),
121
313
            TokenKind::Identifier(value) => self.parse_identifier(token, value),
122
            TokenKind::Open(Balanced::Paren) => {
123
7
                self.nested.push((
124
7
                    token.location.start,
125
7
                    NestedState::Tuple(ListStateExpecting::Value),
126
7
                ));
127
7
                Ok(Event::new(
128
7
                    token.location,
129
7
                    EventKind::BeginNested {
130
7
                        name: None,
131
7
                        kind: Nested::Tuple,
132
7
                    },
133
7
                ))
134
            }
135
            TokenKind::Open(Balanced::Bracket) => {
136
18
                self.nested.push((
137
18
                    token.location.start,
138
18
                    NestedState::List(ListStateExpecting::Value),
139
18
                ));
140
18
                Ok(Event::new(
141
18
                    token.location,
142
18
                    EventKind::BeginNested {
143
18
                        name: None,
144
18
                        kind: Nested::List,
145
18
                    },
146
18
                ))
147
            }
148
            TokenKind::Open(Balanced::Brace) => {
149
11
                self.nested.push((
150
11
                    token.location.start,
151
11
                    NestedState::Map(MapStateExpecting::Key),
152
11
                ));
153
11
                Ok(Event::new(
154
11
                    token.location,
155
11
                    EventKind::BeginNested {
156
11
                        name: None,
157
11
                        kind: Nested::Map,
158
11
                    },
159
11
                ))
160
            }
161
15
            TokenKind::Close(closed) if Some(closed) == allowed_close => {
162
15
                self.nested.pop();
163
15
                Ok(Event::new(token.location, EventKind::EndNested))
164
            }
165
            TokenKind::Colon | TokenKind::Comma | TokenKind::Close(_) => {
166
                Err(Error::new(token.location, ErrorKind::ExpectedValue))
167
            }
168
            TokenKind::Comment(comment) => {
169
                Ok(Event::new(token.location, EventKind::Comment(comment)))
170
            }
171
            TokenKind::Whitespace(_) => unreachable!("disabled"),
172
        }
173
691
    }
174

            
175
313
    fn parse_identifier(&mut self, token: Token<'s>, value: &'s str) -> Result<Event<'s>, Error> {
176
275
        if matches!(
177
313
            self.peek(),
178
            Some(Token {
179
                kind: TokenKind::Open(Balanced::Brace | Balanced::Paren),
180
                ..
181
            })
182
        ) {
183
            let Some(Ok(Token {
184
38
                kind: TokenKind::Open(balanced),
185
38
                location: open_location,
186
38
            })) = self.next_token()
187
            else {
188
                unreachable!("matched above")
189
            };
190

            
191
38
            let kind = match balanced {
192
                Balanced::Paren => {
193
16
                    self.nested.push((
194
16
                        open_location.start,
195
16
                        NestedState::Tuple(ListStateExpecting::Value),
196
16
                    ));
197
16
                    Nested::Tuple
198
                }
199
                Balanced::Brace => {
200
22
                    self.nested.push((
201
22
                        open_location.start,
202
22
                        NestedState::Map(MapStateExpecting::Key),
203
22
                    ));
204
22
                    Nested::Map
205
                }
206
                Balanced::Bracket => {
207
                    unreachable!("specifically excluded above")
208
                }
209
            };
210

            
211
38
            Ok(Event::new(
212
38
                open_location,
213
38
                EventKind::BeginNested {
214
38
                    name: Some(Name {
215
38
                        location: token.location,
216
38
                        name: value,
217
38
                    }),
218
38
                    kind,
219
38
                },
220
38
            ))
221
274
        } else if matches!(
222
275
            self.peek(),
223
            Some(Token {
224
                kind: TokenKind::Open(Balanced::Bracket),
225
                ..
226
            })
227
        ) {
228
1
            let location = self.peek().expect("just matched").location.clone();
229
1
            return Err(Error::new(location, ErrorKind::ExpectedMapOrTuple));
230
        } else {
231
274
            Ok(Event::new(
232
274
                token.location,
233
274
                EventKind::Primitive(Primitive::Identifier(value)),
234
274
            ))
235
        }
236
313
    }
237

            
238
172
    fn parse_sequence(
239
172
        &mut self,
240
172
        state: ListStateExpecting,
241
172
        end: Balanced,
242
172
    ) -> Result<Event<'s>, Error> {
243
172
        match state {
244
            ListStateExpecting::Value => {
245
89
                let token = self.next_or_eof()?;
246
89
                if let TokenKind::Comment(comment) = &token.kind {
247
2
                    Ok(Event::new(token.location, EventKind::Comment(comment)))
248
                } else {
249
87
                    self.nested.last_mut().expect("required for this fn").1 =
250
87
                        NestedState::list(end, ListStateExpecting::Comma);
251
87
                    self.parse_token(token, Some(end))
252
                }
253
            }
254
83
            ListStateExpecting::Comma => match self.next_token_parts()? {
255
35
                (location, Some(TokenKind::Close(closed))) if closed == end => {
256
35
                    self.nested.pop();
257
35
                    Ok(Event::new(location, EventKind::EndNested))
258
                }
259
                (_, Some(TokenKind::Comma)) => {
260
46
                    self.nested.last_mut().expect("required for this fn").1 =
261
46
                        NestedState::list(end, ListStateExpecting::Value);
262
46
                    self.parse_sequence(ListStateExpecting::Value, end)
263
                }
264
2
                (location, Some(TokenKind::Comment(comment))) => {
265
2
                    Ok(Event::new(location, EventKind::Comment(comment)))
266
                }
267
                (location, _) => Err(Error::new(
268
                    location,
269
                    ErrorKind::ExpectedCommaOrEnd(end.into()),
270
                )),
271
            },
272
        }
273
172
    }
274

            
275
865
    fn map_state_mut(&mut self) -> &mut MapStateExpecting {
276
865
        let Some((_, NestedState::Map(map_state))) = self.nested.last_mut() else {
277
            unreachable!("not a map state")
278
        };
279
865
        map_state
280
865
    }
281

            
282
897
    fn parse_map(&mut self, state: MapStateExpecting) -> Result<Event<'s>, Error> {
283
897
        match state {
284
231
            MapStateExpecting::Key => match self.next_token().transpose()? {
285
                Some(Token {
286
2
                    kind: TokenKind::Comment(comment),
287
2
                    location,
288
2
                }) => Ok(Event::new(location, EventKind::Comment(comment))),
289
229
                Some(token) => {
290
229
                    *self.map_state_mut() = MapStateExpecting::Colon;
291
229
                    self.parse_token(token, Some(Balanced::Brace))
292
                }
293
                None => Err(Error::new(
294
                    self.tokens.current_offset()..self.tokens.current_offset(),
295
                    ErrorKind::ExpectedKey,
296
                )),
297
            },
298
222
            MapStateExpecting::Colon => match self.next_token_parts()? {
299
                (_, Some(TokenKind::Colon)) => {
300
220
                    *self.map_state_mut() = MapStateExpecting::Value;
301
220
                    self.parse_map(MapStateExpecting::Value)
302
                }
303
2
                (location, Some(TokenKind::Comment(comment))) => {
304
2
                    Ok(Event::new(location, EventKind::Comment(comment)))
305
                }
306
                (location, _) => Err(Error::new(location, ErrorKind::ExpectedColon)),
307
            },
308
222
            MapStateExpecting::Value => match self.next_token().transpose()? {
309
                Some(Token {
310
2
                    kind: TokenKind::Comment(comment),
311
2
                    location,
312
2
                }) => Ok(Event::new(location, EventKind::Comment(comment))),
313
220
                Some(token) => {
314
220
                    *self.map_state_mut() = MapStateExpecting::Comma;
315
220
                    self.parse_token(token, None)
316
                }
317
                None => Err(Error::new(
318
                    self.tokens.current_offset()..self.tokens.current_offset(),
319
                    ErrorKind::ExpectedValue,
320
                )),
321
            },
322
222
            MapStateExpecting::Comma => match self.next_token_parts()? {
323
24
                (location, Some(TokenKind::Close(Balanced::Brace))) => {
324
24
                    self.nested.pop();
325
24
                    Ok(Event::new(location, EventKind::EndNested))
326
                }
327
                (_, Some(TokenKind::Comma)) => {
328
196
                    *self.map_state_mut() = MapStateExpecting::Key;
329
196
                    self.parse_map(MapStateExpecting::Key)
330
                }
331
2
                (location, Some(TokenKind::Comment(comment))) => {
332
2
                    Ok(Event::new(location, EventKind::Comment(comment)))
333
                }
334
                (location, _) => Err(Error::new(
335
                    location,
336
                    ErrorKind::ExpectedCommaOrEnd(Nested::Map),
337
                )),
338
            },
339
        }
340
897
    }
341

            
342
164
    fn parse_implicit_map(&mut self, state: MapStateExpecting) -> Result<Event<'s>, Error> {
343
164
        match state {
344
2
            MapStateExpecting::Key => match self.next_token().transpose()? {
345
                Some(Token {
346
                    location,
347
                    kind: TokenKind::Comment(comment),
348
                }) => Ok(Event::new(location, EventKind::Comment(comment))),
349
1
                Some(token) => match self.parse_token(token, None)? {
350
                    Event {
351
1
                        kind: EventKind::Primitive(primitive),
352
1
                        location,
353
1
                    } => {
354
1
                        self.root_state = State::ImplicitMap(MapStateExpecting::Colon);
355
1
                        Ok(Event::new(location, EventKind::Primitive(primitive)))
356
                    }
357
                    Event { location, .. } => Err(Error::new(location, ErrorKind::ExpectedKey)),
358
                },
359
                None => {
360
1
                    self.root_state = State::Finished;
361
1
                    Ok(Event::new(self.current_range(), EventKind::EndNested))
362
                }
363
            },
364
54
            MapStateExpecting::Colon => match self.next_token_parts()? {
365
                (_, Some(TokenKind::Colon)) => {
366
54
                    self.root_state = State::ImplicitMap(MapStateExpecting::Value);
367
54
                    self.parse_implicit_map(MapStateExpecting::Value)
368
                }
369
                (location, Some(TokenKind::Comment(comment))) => {
370
                    Ok(Event::new(location, EventKind::Comment(comment)))
371
                }
372
                (location, _) => Err(Error::new(location, ErrorKind::ExpectedColon)),
373
            },
374
54
            MapStateExpecting::Value => match self.next_token().transpose()? {
375
                Some(Token {
376
                    kind: TokenKind::Comment(comment),
377
                    location,
378
                }) => Ok(Event::new(location, EventKind::Comment(comment))),
379
54
                Some(token) => {
380
54
                    self.root_state = State::ImplicitMap(MapStateExpecting::Comma);
381
54
                    self.parse_token(token, None)
382
                }
383
                None => Err(Error::new(
384
                    self.tokens.current_offset()..self.tokens.current_offset(),
385
                    ErrorKind::ExpectedValue,
386
                )),
387
            },
388
54
            MapStateExpecting::Comma => match self.next_token().transpose()? {
389
                Some(Token {
390
                    location,
391
                    kind: TokenKind::Comment(comment),
392
                }) => Ok(Event::new(location, EventKind::Comment(comment))),
393
                Some(Token {
394
                    location,
395
                    kind: TokenKind::Close(Balanced::Brace),
396
                }) => {
397
                    self.root_state = State::Finished;
398
                    Ok(Event::new(location, EventKind::EndNested))
399
                }
400
                Some(Token {
401
                    kind: TokenKind::Comma,
402
                    ..
403
                }) => {
404
2
                    self.root_state = State::ImplicitMap(MapStateExpecting::Key);
405
2
                    self.parse_implicit_map(MapStateExpecting::Key)
406
                }
407
47
                Some(token) => {
408
47
                    self.root_state = State::ImplicitMap(MapStateExpecting::Colon);
409
47
                    match self.parse_token(token, None)? {
410
                        Event {
411
47
                            location,
412
47
                            kind: EventKind::Primitive(primitive),
413
47
                        } => Ok(Event::new(location, EventKind::Primitive(primitive))),
414
                        Event { location, .. } => Err(Error::new(location, ErrorKind::ExpectedKey)),
415
                    }
416
                }
417
                None => {
418
5
                    self.root_state = State::Finished;
419
5
                    Ok(Event::new(self.current_range(), EventKind::EndNested))
420
                }
421
            },
422
        }
423
164
    }
424

            
425
828
    fn next_event(&mut self) -> Option<Result<Event<'s>, Error>> {
426
828
        Some(match self.nested.last() {
427
221
            None => match &self.root_state {
428
                State::AtStart => {
429
54
                    let token = match self.next_token()? {
430
54
                        Ok(token) => token,
431
                        Err(err) => return Some(Err(err.into())),
432
                    };
433
53
                    match &token.kind {
434
1
                        TokenKind::Comment(comment) => {
435
1
                            Ok(Event::new(token.location, EventKind::Comment(comment)))
436
                        }
437
53
                        _ if self.config.allow_implicit_map_at_root
438
5
                            && matches!(
439
11
                                self.peek(),
440
                                Some(Token {
441
                                    kind: TokenKind::Colon,
442
                                    ..
443
                                })
444
6
                            ) =>
445
6
                        {
446
6
                            match self.parse_token(token, None) {
447
6
                                Ok(event) => {
448
6
                                    self.root_state = State::StartingImplicitMap(event);
449
6
                                    Ok(Event::new(
450
6
                                        0..0,
451
6
                                        EventKind::BeginNested {
452
6
                                            name: None,
453
6
                                            kind: Nested::Map,
454
6
                                        },
455
6
                                    ))
456
                                }
457
                                Err(err) => Err(err),
458
                            }
459
                        }
460
                        _ => {
461
47
                            self.root_state = State::Finished;
462
47
                            self.parse_token(token, None)
463
                        }
464
                    }
465
                }
466
                State::StartingImplicitMap(_) => {
467
6
                    let State::StartingImplicitMap(event) = mem::replace(
468
6
                        &mut self.root_state,
469
6
                        State::ImplicitMap(MapStateExpecting::Colon),
470
6
                    ) else {
471
                        unreachable!("just matched")
472
                    };
473
6
                    Ok(event)
474
                }
475
108
                State::ImplicitMap(state) => self.parse_implicit_map(*state),
476
53
                State::Finished => match self.next_token()? {
477
1
                    Ok(token) => match token.kind {
478
1
                        TokenKind::Comment(comment) => {
479
1
                            Ok(Event::new(token.location, EventKind::Comment(comment)))
480
                        }
481
                        TokenKind::Whitespace(_) => unreachable!("disabled"),
482
                        _ => Err(Error::new(token.location, ErrorKind::TrailingData)),
483
                    },
484
                    Err(err) => Err(err.into()),
485
                },
486
            },
487

            
488
58
            Some((_, NestedState::Tuple(list))) => self.parse_sequence(*list, Balanced::Paren),
489
68
            Some((_, NestedState::List(list))) => self.parse_sequence(*list, Balanced::Bracket),
490
481
            Some((_, NestedState::Map(map))) => self.parse_map(*map),
491
        })
492
828
    }
493
}
494

            
495
impl<'s> Iterator for Parser<'s> {
496
    type Item = Result<Event<'s>, Error>;
497

            
498
828
    fn next(&mut self) -> Option<Self::Item> {
499
        loop {
500
828
            let event = self.next_event()?;
501
776
            if self.config.include_comments
502
753
                || !matches!(
503
752
                    event,
504
                    Ok(Event {
505
                        kind: EventKind::Comment(_),
506
                        ..
507
                    })
508
                )
509
            {
510
776
                break Some(event);
511
            }
512

            
513
            // Eat the comment
514
        }
515
828
    }
516
}
517

            
518
/// The configuration of a [`Parser`].
519
#[derive(Default, Debug, Clone, Copy)]
520
#[non_exhaustive]
521
pub struct Config {
522
    /// Allows parsing an implicit map at the root of the Rsn document.
523
    ///
524
    /// Rsn allows root-level syntax that may be desirable when using it as a
525
    /// configuration-like file format.
526
    ///
527
    /// Implicit map:
528
    /// ```rsn
529
    /// name: "John Doe"
530
    /// age: 40
531
    /// ```
532
    ///
533
    /// Normal map:
534
    /// ```rsn
535
    /// {
536
    ///     name: "John Doe",
537
    ///     age: 40,
538
    /// }
539
    /// ```
540
    ///
541
    /// When set to true, the parser will allow both implicit and explicit
542
    /// syntaxes at the root of the document. When set to false, the parser will
543
    /// only allow explicit maps.
544
    pub allow_implicit_map_at_root: bool,
545
    /// When true, the parser will include [`EventKind::Comment`] events.
546
    pub include_comments: bool,
547
}
548

            
549
impl Config {
550
    /// Sets [`Config::allow_implicit_map_at_root`] to `allow` and returns self.
551
    #[must_use]
552
8
    pub const fn allow_implicit_map_at_root(mut self, allow: bool) -> Self {
553
8
        self.allow_implicit_map_at_root = allow;
554
8
        self
555
8
    }
556

            
557
    /// Sets [`Config::include_comments`] to `include` and returns self.
558
    #[must_use]
559
46
    pub const fn include_comments(mut self, include: bool) -> Self {
560
46
        self.include_comments = include;
561
46
        self
562
46
    }
563
}
564

            
565
#[derive(Debug, Clone, PartialEq)]
566
enum State<'s> {
567
    AtStart,
568
    StartingImplicitMap(Event<'s>),
569
    ImplicitMap(MapStateExpecting),
570
    Finished,
571
}
572

            
573
/// An error that arose while parsing Rsn events.
574
#[derive(Debug, Clone, Eq, PartialEq)]
575
pub struct Error {
576
    /// The byte range of this error.
577
    pub location: Range<usize>,
578
    /// The kind of error that occurred.
579
    pub kind: ErrorKind,
580
}
581

            
582
impl Error {
583
    #[must_use]
584
2
    pub(crate) fn new(location: Range<usize>, kind: ErrorKind) -> Self {
585
2
        Self { location, kind }
586
2
    }
587
}
588

            
589
#[cfg(feature = "std")]
590
impl std::error::Error for Error {}
591

            
592
impl Display for Error {
593
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
594
        Display::fmt(&self.kind, f)
595
    }
596
}
597

            
598
impl From<tokenizer::Error> for Error {
599
    fn from(err: tokenizer::Error) -> Self {
600
        Self {
601
            location: err.location,
602
            kind: err.kind.into(),
603
        }
604
    }
605
}
606

            
607
/// A kind of error that arose while parsing Rsn events.
608
#[derive(Debug, Clone, Eq, PartialEq)]
609
#[non_exhaustive]
610
pub enum ErrorKind {
611
    /// An error occurred tokenizing the input.
612
    Tokenizer(tokenizer::ErrorKind),
613
    /// An end-of-file error was encountered when data was still expected.
614
    UnexpectedEof,
615
    /// A key in a map was expected.
616
    ExpectedKey,
617
    /// A `:` was expected.
618
    ExpectedColon,
619
    /// A value was expected.
620
    ///
621
    /// This may be encountered in both sequence (list/tuple) parsing and map
622
    /// parsing.
623
    ExpectedValue,
624
    /// Expected a `,` or the end-variant of the specified [`Nested`].
625
    ExpectedCommaOrEnd(Nested),
626
    /// Expected either a map or a tuple.
627
    ExpectedMapOrTuple,
628
    /// Additional data was found after a complete value was parsed.
629
    TrailingData,
630
}
631

            
632
impl From<tokenizer::ErrorKind> for ErrorKind {
633
    fn from(kind: tokenizer::ErrorKind) -> Self {
634
        Self::Tokenizer(kind)
635
    }
636
}
637

            
638
impl Display for ErrorKind {
639
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
640
        match self {
641
            ErrorKind::Tokenizer(err) => Display::fmt(err, f),
642
            ErrorKind::UnexpectedEof => f.write_str("unexpected end of file"),
643
            ErrorKind::ExpectedValue => f.write_str("a value was expected"),
644
            ErrorKind::ExpectedCommaOrEnd(nested) => {
645
                write!(f, "expected `,` or {}", nested.err_display())
646
            }
647
            ErrorKind::ExpectedColon => f.write_str("expected `:`"),
648
            ErrorKind::ExpectedKey => f.write_str("expected map key"),
649
            ErrorKind::TrailingData => f.write_str(
650
                "source contained extra trailing data after a value was completely read",
651
            ),
652
            ErrorKind::ExpectedMapOrTuple => {
653
                f.write_str("[ is not valid for a named value, expected { or (")
654
            }
655
        }
656
    }
657
}
658

            
659
/// A Rsn event from parsing Rsn.
660
#[derive(Debug, Clone, PartialEq)]
661
pub struct Event<'s> {
662
    /// The byte offset of the source that produced this event.
663
    pub location: Range<usize>,
664
    /// The kind of this event.
665
    pub kind: EventKind<'s>,
666
}
667

            
668
impl<'s> Event<'s> {
669
    #[must_use]
670
878
    fn new(location: Range<usize>, kind: EventKind<'s>) -> Self {
671
878
        Self { location, kind }
672
878
    }
673
}
674

            
675
/// A kind of an event encountered when parsing Rsn.
676
#[derive(Debug, PartialEq, Clone)]
677
pub enum EventKind<'s> {
678
    /// A nested sequence of events has started.
679
    ///
680
    /// The next events "belong" to this nesting until a matching
681
    /// [`EventKind::EndNested`] is encountered.
682
    BeginNested {
683
        /// The name of this nested context, if encountered.
684
        name: Option<Name<'s>>,
685
        /// The type of nesting.
686
        kind: Nested,
687
    },
688
    /// A nested sequence of events has concluded.
689
    ///
690
    /// This event can only be encountered after a [`EventKind::BeginNested`]
691
    /// has been encountered. Only valid nesting equences can be encountered. If
692
    /// nesting cannot be matched, an error will be returned.
693
    EndNested,
694
    /// A primitive literal.
695
    Primitive(Primitive<'s>),
696
    /// A comment.
697
    Comment(&'s str),
698
}
699

            
700
/// A name/identifier.
701
#[derive(Debug, PartialEq, Clone)]
702
pub struct Name<'s> {
703
    /// The byte range of the name in the source.
704
    pub location: Range<usize>,
705
    /// The name/identifier.
706
    pub name: &'s str,
707
}
708

            
709
impl<'s> Deref for Name<'s> {
710
    type Target = str;
711

            
712
17
    fn deref(&self) -> &Self::Target {
713
17
        self.name
714
17
    }
715
}
716

            
717
impl<'s> PartialEq<str> for Name<'s> {
718
    fn eq(&self, other: &str) -> bool {
719
        self.name == other
720
    }
721
}
722

            
723
impl<'a, 's> PartialEq<&'a str> for Name<'s> {
724
17
    fn eq(&self, other: &&'a str) -> bool {
725
17
        self.name == *other
726
17
    }
727
}
728

            
729
/// A kind of nestable types.
730
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
731
pub enum Nested {
732
    /// A sequence of values enclosed by parentheses.
733
    Tuple,
734
    /// A sequence of key-value pairs enclosed by curly braces.
735
    Map,
736
    /// A sequence of values enclosed by square brackets.
737
    List,
738
}
739

            
740
impl Nested {
741
    fn err_display(self) -> &'static str {
742
        match self {
743
            Nested::Tuple => "`)`",
744
            Nested::Map => "`}`",
745
            Nested::List => "`]`",
746
        }
747
    }
748
}
749

            
750
impl From<Balanced> for Nested {
751
    fn from(kind: Balanced) -> Self {
752
        match kind {
753
            Balanced::Paren => Self::Tuple,
754
            Balanced::Bracket => Self::List,
755
            Balanced::Brace => Self::Map,
756
        }
757
    }
758
}
759

            
760
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
761
enum NestedState {
762
    Tuple(ListStateExpecting),
763
    List(ListStateExpecting),
764
    Map(MapStateExpecting),
765
}
766

            
767
impl NestedState {
768
133
    fn list(kind: Balanced, state: ListStateExpecting) -> Self {
769
133
        match kind {
770
53
            Balanced::Paren => Self::Tuple(state),
771
80
            Balanced::Bracket => Self::List(state),
772
            Balanced::Brace => unreachable!("Brace must receive a MapState"),
773
        }
774
133
    }
775
}
776

            
777
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
778
enum ListStateExpecting {
779
    Value,
780
    Comma,
781
}
782

            
783
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
784
enum MapStateExpecting {
785
    Key,
786
    Colon,
787
    Value,
788
    Comma,
789
}
790

            
791
/// A primitive literal.
792
#[derive(Debug, PartialEq, Clone)]
793
pub enum Primitive<'s> {
794
    /// A boolean literal.
795
    Bool(bool),
796
    /// An integer literal.
797
    Integer(Integer),
798
    /// A floating point literal.
799
    Float(f64),
800
    /// A character literal.
801
    Char(char),
802
    /// A string literal.
803
    String(Cow<'s, str>),
804
    /// An identifier.
805
    Identifier(&'s str),
806
    /// A byte string literal.
807
    Bytes(Cow<'s, [u8]>),
808
}
809

            
810
#[cfg(test)]
811
mod tests {
812
    use super::*;
813
    #[test]
814
1
    fn number_array() {
815
1
        let events = Parser::new("[1,2,3]", Config::default())
816
1
            .collect::<Result<Vec<_>, _>>()
817
1
            .unwrap();
818
1
        assert_eq!(
819
1
            &events,
820
1
            &[
821
1
                Event::new(
822
1
                    0..1,
823
1
                    EventKind::BeginNested {
824
1
                        name: None,
825
1
                        kind: Nested::List
826
1
                    }
827
1
                ),
828
1
                Event::new(
829
1
                    1..2,
830
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
831
1
                ),
832
1
                Event::new(
833
1
                    3..4,
834
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
835
1
                ),
836
1
                Event::new(
837
1
                    5..6,
838
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(3)))
839
1
                ),
840
1
                Event::new(6..7, EventKind::EndNested),
841
1
            ]
842
1
        );
843
1
        let events = Parser::new("[1,2,3,]", Config::default())
844
1
            .collect::<Result<Vec<_>, _>>()
845
1
            .unwrap();
846
1
        assert_eq!(
847
1
            &events,
848
1
            &[
849
1
                Event::new(
850
1
                    0..1,
851
1
                    EventKind::BeginNested {
852
1
                        name: None,
853
1
                        kind: Nested::List
854
1
                    }
855
1
                ),
856
1
                Event::new(
857
1
                    1..2,
858
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
859
1
                ),
860
1
                Event::new(
861
1
                    3..4,
862
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
863
1
                ),
864
1
                Event::new(
865
1
                    5..6,
866
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(3)))
867
1
                ),
868
1
                Event::new(7..8, EventKind::EndNested),
869
1
            ]
870
1
        );
871
1
    }
872

            
873
    #[test]
874
1
    fn number_tuple() {
875
1
        let events = Parser::new("(1,2,3)", Config::default())
876
1
            .collect::<Result<Vec<_>, _>>()
877
1
            .unwrap();
878
1
        assert_eq!(
879
1
            &events,
880
1
            &[
881
1
                Event::new(
882
1
                    0..1,
883
1
                    EventKind::BeginNested {
884
1
                        name: None,
885
1
                        kind: Nested::Tuple
886
1
                    }
887
1
                ),
888
1
                Event::new(
889
1
                    1..2,
890
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
891
1
                ),
892
1
                Event::new(
893
1
                    3..4,
894
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
895
1
                ),
896
1
                Event::new(
897
1
                    5..6,
898
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(3)))
899
1
                ),
900
1
                Event::new(6..7, EventKind::EndNested),
901
1
            ]
902
1
        );
903
1
        let events = Parser::new("(1,2,3,)", Config::default())
904
1
            .collect::<Result<Vec<_>, _>>()
905
1
            .unwrap();
906
1
        assert_eq!(
907
1
            &events,
908
1
            &[
909
1
                Event::new(
910
1
                    0..1,
911
1
                    EventKind::BeginNested {
912
1
                        name: None,
913
1
                        kind: Nested::Tuple
914
1
                    }
915
1
                ),
916
1
                Event::new(
917
1
                    1..2,
918
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
919
1
                ),
920
1
                Event::new(
921
1
                    3..4,
922
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
923
1
                ),
924
1
                Event::new(
925
1
                    5..6,
926
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(3)))
927
1
                ),
928
1
                Event::new(7..8, EventKind::EndNested),
929
1
            ]
930
1
        );
931
1
    }
932

            
933
    #[test]
934
1
    fn number_map() {
935
1
        let events = Parser::new("{a:1,b:2}", Config::default())
936
1
            .collect::<Result<Vec<_>, _>>()
937
1
            .unwrap();
938
1
        assert_eq!(
939
1
            &events,
940
1
            &[
941
1
                Event::new(
942
1
                    0..1,
943
1
                    EventKind::BeginNested {
944
1
                        name: None,
945
1
                        kind: Nested::Map
946
1
                    }
947
1
                ),
948
1
                Event::new(1..2, EventKind::Primitive(Primitive::Identifier("a"))),
949
1
                Event::new(
950
1
                    3..4,
951
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
952
1
                ),
953
1
                Event::new(5..6, EventKind::Primitive(Primitive::Identifier("b"))),
954
1
                Event::new(
955
1
                    7..8,
956
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
957
1
                ),
958
1
                Event::new(8..9, EventKind::EndNested),
959
1
            ]
960
1
        );
961
1
        let events = Parser::new("{a:1,b:2,}", Config::default())
962
1
            .collect::<Result<Vec<_>, _>>()
963
1
            .unwrap();
964
1
        assert_eq!(
965
1
            &events,
966
1
            &[
967
1
                Event::new(
968
1
                    0..1,
969
1
                    EventKind::BeginNested {
970
1
                        name: None,
971
1
                        kind: Nested::Map
972
1
                    }
973
1
                ),
974
1
                Event::new(1..2, EventKind::Primitive(Primitive::Identifier("a"))),
975
1
                Event::new(
976
1
                    3..4,
977
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
978
1
                ),
979
1
                Event::new(5..6, EventKind::Primitive(Primitive::Identifier("b"))),
980
1
                Event::new(
981
1
                    7..8,
982
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
983
1
                ),
984
1
                Event::new(9..10, EventKind::EndNested),
985
1
            ]
986
1
        );
987
1
    }
988

            
989
    #[test]
990
1
    fn commented() {
991
1
        let events = Parser::new(
992
1
            "/**/{/**/a/**/:/**/1/**/,/**/b/**/:/**/[/**/2/**/,/**/3/**/]/**/}/**/",
993
1
            Config::default().include_comments(true),
994
1
        )
995
1
        .collect::<Result<Vec<_>, _>>()
996
1
        .unwrap();
997
1
        assert_eq!(
998
1
            &events,
999
1
            &[
1
                Event::new(0..4, EventKind::Comment("/**/")),
1
                Event::new(
1
                    4..5,
1
                    EventKind::BeginNested {
1
                        name: None,
1
                        kind: Nested::Map
1
                    }
1
                ),
1
                Event::new(5..9, EventKind::Comment("/**/")),
1
                Event::new(9..10, EventKind::Primitive(Primitive::Identifier("a"))),
1
                Event::new(10..14, EventKind::Comment("/**/")),
1
                Event::new(15..19, EventKind::Comment("/**/")),
1
                Event::new(
1
                    19..20,
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(1)))
1
                ),
1
                Event::new(20..24, EventKind::Comment("/**/")),
1
                Event::new(25..29, EventKind::Comment("/**/")),
1
                Event::new(29..30, EventKind::Primitive(Primitive::Identifier("b"))),
1
                Event::new(30..34, EventKind::Comment("/**/")),
1
                Event::new(35..39, EventKind::Comment("/**/")),
1
                Event::new(
1
                    39..40,
1
                    EventKind::BeginNested {
1
                        name: None,
1
                        kind: Nested::List
1
                    }
1
                ),
1
                Event::new(40..44, EventKind::Comment("/**/")),
1
                Event::new(
1
                    44..45,
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(2)))
1
                ),
1
                Event::new(45..49, EventKind::Comment("/**/")),
1
                Event::new(50..54, EventKind::Comment("/**/")),
1
                Event::new(
1
                    54..55,
1
                    EventKind::Primitive(Primitive::Integer(Integer::Usize(3)))
1
                ),
1
                Event::new(55..59, EventKind::Comment("/**/")),
1
                Event::new(59..60, EventKind::EndNested),
1
                Event::new(60..64, EventKind::Comment("/**/")),
1
                Event::new(64..65, EventKind::EndNested),
1
                Event::new(65..69, EventKind::Comment("/**/")),
1
            ]
1
        );
1
    }

            
    #[test]
1
    fn array_named_error() {
1
        let err = Parser::new("Foo[]", Config::default())
1
            .next()
1
            .unwrap()
1
            .unwrap_err();
1
        assert_eq!(err, Error::new(3..4, ErrorKind::ExpectedMapOrTuple));
1
    }
}