decent_toml_rs_alternative/
parser.rs

1
2// File based on code from Alex Crichton’s toml-rs library
3// https://github.com/alexcrichton/toml-rs/
4// Copyright (c) 2014 Alex Crichton
5
6//! Parsing TOML files line by line according to the TOML grammar, without validating the whole TOML file
7use std::borrow::Cow;
8use std::error;
9use std::f64;
10use std::fmt;
11use std::str;
12
13use crate::tokens::{Error as TokenError, Span, Token, Tokenizer};
14
15pub fn parse_toml_lines(input: &str) -> Result<Vec<Line<'_>>, Error> {
16    let mut parser = Parser::new(input);
17    let mut lines = vec![];
18    while let Some(line) = parser.line()? {
19        lines.push(line);
20    }
21    Ok(lines)
22}
23
24/// Type Alias for a TOML Table pair
25type TablePair<'a> = ((Span, Cow<'a, str>), Value<'a>);
26
27/// Errors that can occur when parsing
28#[derive(Debug, PartialEq, Eq, Clone)]
29pub struct Error {
30    inner: Box<ErrorInner>,
31}
32
33#[derive(Debug, PartialEq, Eq, Clone)]
34struct ErrorInner {
35    kind: ErrorKind,
36    line: Option<usize>,
37    col: usize,
38    at: Option<usize>,
39    message: String,
40    key: Vec<String>,
41}
42
43/// Errors that can occur when parsing
44#[derive(Debug, PartialEq, Eq, Clone)]
45enum ErrorKind {
46    /// EOF was reached when looking for a value
47    UnexpectedEof,
48
49    /// An invalid character not allowed in a string was found
50    InvalidCharInString(char),
51
52    /// An invalid character was found as an escape
53    InvalidEscape(char),
54
55    /// An invalid character was found in a hex escape
56    InvalidHexEscape(char),
57
58    /// An invalid escape value was specified in a hex escape in a string.
59    ///
60    /// Valid values are in the plane of unicode codepoints.
61    InvalidEscapeValue(u32),
62
63    /// A newline in a string was encountered when one was not allowed.
64    NewlineInString,
65
66    /// An unexpected character was encountered, typically when looking for a
67    /// value.
68    Unexpected(char),
69
70    /// An unterminated string was found where EOF was found before the ending
71    /// EOF mark.
72    UnterminatedString,
73
74    /// A newline was found in a table key.
75    NewlineInTableKey,
76
77    /// A number failed to parse
78    NumberInvalid,
79
80    /// A date or datetime was invalid
81    DateInvalid,
82
83    /// Wanted one sort of token, but found another.
84    Wanted {
85        /// Expected token type
86        expected: &'static str,
87        /// Actually found token type
88        found: &'static str,
89    },
90
91    /// An empty table key was found.
92    EmptyTableKey,
93
94    /// Multiline strings are not allowed for key
95    MultilineStringKey,
96
97    /// Dotted key attempted to extend something that is not a table.
98    DottedKeyInvalidType,
99
100    #[doc(hidden)]
101    __Nonexhaustive,
102}
103
104/// Parser implementation for TOML.
105pub struct Parser<'a> {
106    input: &'a str,
107    tokens: Tokenizer<'a>,
108}
109
110#[derive(Debug)]
111struct Table<'a> {
112    at: usize,
113    header: Vec<(Span, Cow<'a, str>)>,
114    values: Option<Vec<TablePair<'a>>>,
115    array: bool,
116}
117
118impl<'a> Parser<'a> {
119    /// Creates a new parser which will be parsing the string provided.
120    fn new(input: &'a str) -> Parser<'a> {
121        Parser {
122            tokens: Tokenizer::new(input),
123            input,
124        }
125    }
126
127    fn line(&mut self) -> Result<Option<Line<'a>>, Error> {
128        // TODO: parse comments
129        loop {
130            self.eat_whitespace()?;
131            if self.eat_comment()? {
132                continue;
133            }
134            if self.eat(Token::Newline)? {
135                continue;
136            }
137            break;
138        }
139
140        match self.peek()? {
141            Some((_, Token::LeftBracket)) => self.table_header().map(Some),
142            Some(_) => self.key_value().map(Some),
143            None => Ok(None),
144        }
145    }
146
147    fn table_header(&mut self) -> Result<Line<'a>, Error> {
148        let start = self.tokens.current();
149        self.expect(Token::LeftBracket)?;
150        let array = self.eat(Token::LeftBracket)?;
151        let ret = Header::new(self.tokens.clone(), array);
152        self.tokens.skip_to_newline();
153        Ok(Line::Table {
154            at: start,
155            header: ret,
156            array,
157        })
158    }
159
160    fn key_value(&mut self) -> Result<Line<'a>, Error> {
161        let key = self.dotted_key()?;
162        self.eat_whitespace()?;
163        self.expect(Token::Equals)?;
164        self.eat_whitespace()?;
165
166        let value = self.value()?;
167        self.eat_whitespace()?;
168        if !self.eat_comment()? {
169            self.eat_newline_or_eof()?;
170        }
171
172        Ok(Line::KeyValue(key, value))
173    }
174
175    fn value(&mut self) -> Result<Value<'a>, Error> {
176        let at = self.tokens.current();
177        let value = match self.next()? {
178            Some((Span { start, end }, Token::String { val, .. })) => Value {
179                e: ValueKind::String(val),
180                start,
181                end,
182            },
183            Some((Span { start, end }, Token::Keylike("true"))) => Value {
184                e: ValueKind::Boolean(true),
185                start,
186                end,
187            },
188            Some((Span { start, end }, Token::Keylike("false"))) => Value {
189                e: ValueKind::Boolean(false),
190                start,
191                end,
192            },
193            Some((span, Token::Keylike(key))) => self.number_or_date(span, key)?,
194            Some((span, Token::Plus)) => self.number_leading_plus(span)?,
195            Some((Span { start, .. }, Token::LeftBrace)) => {
196                self.inline_table().map(|(Span { end, .. }, table)| Value {
197                    e: ValueKind::InlineTable(table),
198                    start,
199                    end,
200                })?
201            }
202            Some((Span { start, .. }, Token::LeftBracket)) => {
203                self.array().map(|(Span { end, .. }, array)| Value {
204                    e: ValueKind::Array(array),
205                    start,
206                    end,
207                })?
208            }
209            Some(token) => {
210                return Err(self.error(
211                    at,
212                    ErrorKind::Wanted {
213                        expected: "a value",
214                        found: token.1.describe(),
215                    },
216                ))
217            }
218            None => return Err(self.eof()),
219        };
220        Ok(value)
221    }
222
223    fn number_or_date(&mut self, span: Span, s: &'a str) -> Result<Value<'a>, Error> {
224        if s.contains('T')
225            || s.contains('t')
226            || (s.len() > 1 && s[1..].contains('-') && !s.contains("e-") && !s.contains("E-"))
227        {
228            self.datetime(span, s, false)
229                .map(|(Span { start, end }, d)| Value {
230                    e: ValueKind::Datetime(d),
231                    start,
232                    end,
233                })
234        } else if self.eat(Token::Colon)? {
235            self.datetime(span, s, true)
236                .map(|(Span { start, end }, d)| Value {
237                    e: ValueKind::Datetime(d),
238                    start,
239                    end,
240                })
241        } else {
242            self.number(span, s)
243        }
244    }
245
246    fn number(&mut self, Span { start, end }: Span, s: &'a str) -> Result<Value<'a>, Error> {
247        let to_integer = |f| Value {
248            e: ValueKind::Integer(f),
249            start,
250            end,
251        };
252        if s.starts_with("0x") {
253            self.integer(&s[2..], 16).map(to_integer)
254        } else if s.starts_with("0o") {
255            self.integer(&s[2..], 8).map(to_integer)
256        } else if s.starts_with("0b") {
257            self.integer(&s[2..], 2).map(to_integer)
258        } else if s.contains('e') || s.contains('E') {
259            self.float(s, None).map(|f| Value {
260                e: ValueKind::Float(f),
261                start,
262                end,
263            })
264        } else if self.eat(Token::Period)? {
265            let at = self.tokens.current();
266            match self.next()? {
267                Some((Span { start, end }, Token::Keylike(after))) => {
268                    self.float(s, Some(after)).map(|f| Value {
269                        e: ValueKind::Float(f),
270                        start,
271                        end,
272                    })
273                }
274                _ => Err(self.error(at, ErrorKind::NumberInvalid)),
275            }
276        } else if s == "inf" {
277            Ok(Value {
278                e: ValueKind::Float(f64::INFINITY),
279                start,
280                end,
281            })
282        } else if s == "-inf" {
283            Ok(Value {
284                e: ValueKind::Float(f64::NEG_INFINITY),
285                start,
286                end,
287            })
288        } else if s == "nan" {
289            Ok(Value {
290                e: ValueKind::Float(f64::NAN),
291                start,
292                end,
293            })
294        } else if s == "-nan" {
295            Ok(Value {
296                e: ValueKind::Float(-f64::NAN),
297                start,
298                end,
299            })
300        } else {
301            self.integer(s, 10).map(to_integer)
302        }
303    }
304
305    fn number_leading_plus(&mut self, Span { start, .. }: Span) -> Result<Value<'a>, Error> {
306        let start_token = self.tokens.current();
307        match self.next()? {
308            Some((Span { end, .. }, Token::Keylike(s))) => self.number(Span { start, end }, s),
309            _ => Err(self.error(start_token, ErrorKind::NumberInvalid)),
310        }
311    }
312
313    fn integer(&self, s: &'a str, radix: u32) -> Result<i64, Error> {
314        let allow_sign = radix == 10;
315        let allow_leading_zeros = radix != 10;
316        let (prefix, suffix) = self.parse_integer(s, allow_sign, allow_leading_zeros, radix)?;
317        let start = self.tokens.substr_offset(s);
318        if suffix != "" {
319            return Err(self.error(start, ErrorKind::NumberInvalid));
320        }
321        i64::from_str_radix(&prefix.replace("_", "").trim_start_matches('+'), radix)
322            .map_err(|_e| self.error(start, ErrorKind::NumberInvalid))
323    }
324
325    fn parse_integer(
326        &self,
327        s: &'a str,
328        allow_sign: bool,
329        allow_leading_zeros: bool,
330        radix: u32,
331    ) -> Result<(&'a str, &'a str), Error> {
332        let start = self.tokens.substr_offset(s);
333
334        let mut first = true;
335        let mut first_zero = false;
336        let mut underscore = false;
337        let mut end = s.len();
338        for (i, c) in s.char_indices() {
339            let at = i + start;
340            if i == 0 && (c == '+' || c == '-') && allow_sign {
341                continue;
342            }
343
344            if c == '0' && first {
345                first_zero = true;
346            } else if c.is_digit(radix) {
347                if !first && first_zero && !allow_leading_zeros {
348                    return Err(self.error(at, ErrorKind::NumberInvalid));
349                }
350                underscore = false;
351            } else if c == '_' && first {
352                return Err(self.error(at, ErrorKind::NumberInvalid));
353            } else if c == '_' && !underscore {
354                underscore = true;
355            } else {
356                end = i;
357                break;
358            }
359            first = false;
360        }
361        if first || underscore {
362            return Err(self.error(start, ErrorKind::NumberInvalid));
363        }
364        Ok((&s[..end], &s[end..]))
365    }
366
367    fn float(&mut self, s: &'a str, after_decimal: Option<&'a str>) -> Result<f64, Error> {
368        let (integral, mut suffix) = self.parse_integer(s, true, false, 10)?;
369        let start = self.tokens.substr_offset(integral);
370
371        let mut fraction = None;
372        if let Some(after) = after_decimal {
373            if suffix != "" {
374                return Err(self.error(start, ErrorKind::NumberInvalid));
375            }
376            let (a, b) = self.parse_integer(after, false, true, 10)?;
377            fraction = Some(a);
378            suffix = b;
379        }
380
381        let mut exponent = None;
382        if suffix.starts_with('e') || suffix.starts_with('E') {
383            let (a, b) = if suffix.len() == 1 {
384                self.eat(Token::Plus)?;
385                match self.next()? {
386                    Some((_, Token::Keylike(s))) => self.parse_integer(s, false, true, 10)?,
387                    _ => return Err(self.error(start, ErrorKind::NumberInvalid)),
388                }
389            } else {
390                self.parse_integer(&suffix[1..], true, true, 10)?
391            };
392            if b != "" {
393                return Err(self.error(start, ErrorKind::NumberInvalid));
394            }
395            exponent = Some(a);
396        } else if !suffix.is_empty() {
397            return Err(self.error(start, ErrorKind::NumberInvalid));
398        }
399
400        let mut number = integral
401            .trim_start_matches('+')
402            .chars()
403            .filter(|c| *c != '_')
404            .collect::<String>();
405        if let Some(fraction) = fraction {
406            number.push_str(".");
407            number.extend(fraction.chars().filter(|c| *c != '_'));
408        }
409        if let Some(exponent) = exponent {
410            number.push_str("E");
411            number.extend(exponent.chars().filter(|c| *c != '_'));
412        }
413        number
414            .parse()
415            .map_err(|_e| self.error(start, ErrorKind::NumberInvalid))
416            .and_then(|n: f64| {
417                if n.is_finite() {
418                    Ok(n)
419                } else {
420                    Err(self.error(start, ErrorKind::NumberInvalid))
421                }
422            })
423    }
424
425    fn datetime(
426        &mut self,
427        mut span: Span,
428        date: &'a str,
429        colon_eaten: bool,
430    ) -> Result<(Span, &'a str), Error> {
431        let start = self.tokens.substr_offset(date);
432
433        // Check for space separated date and time.
434        let mut lookahead = self.tokens.clone();
435        if let Ok(Some((_, Token::Whitespace(" ")))) = lookahead.next() {
436            // Check if hour follows.
437            if let Ok(Some((_, Token::Keylike(_)))) = lookahead.next() {
438                self.next()?; // skip space
439                self.next()?; // skip keylike hour
440            }
441        }
442
443        if colon_eaten || self.eat(Token::Colon)? {
444            // minutes
445            match self.next()? {
446                Some((_, Token::Keylike(_))) => {}
447                _ => return Err(self.error(start, ErrorKind::DateInvalid)),
448            }
449            // Seconds
450            self.expect(Token::Colon)?;
451            match self.next()? {
452                Some((Span { end, .. }, Token::Keylike(_))) => {
453                    span.end = end;
454                }
455                _ => return Err(self.error(start, ErrorKind::DateInvalid)),
456            }
457            // Fractional seconds
458            if self.eat(Token::Period)? {
459                match self.next()? {
460                    Some((Span { end, .. }, Token::Keylike(_))) => {
461                        span.end = end;
462                    }
463                    _ => return Err(self.error(start, ErrorKind::DateInvalid)),
464                }
465            }
466
467            // offset
468            if self.eat(Token::Plus)? {
469                match self.next()? {
470                    Some((Span { end, .. }, Token::Keylike(_))) => {
471                        span.end = end;
472                    }
473                    _ => return Err(self.error(start, ErrorKind::DateInvalid)),
474                }
475            }
476            if self.eat(Token::Colon)? {
477                match self.next()? {
478                    Some((Span { end, .. }, Token::Keylike(_))) => {
479                        span.end = end;
480                    }
481                    _ => return Err(self.error(start, ErrorKind::DateInvalid)),
482                }
483            }
484        }
485
486        let end = self.tokens.current();
487        Ok((span, &self.tokens.input()[start..end]))
488    }
489
490    // TODO(#140): shouldn't buffer up this entire table in memory, it'd be
491    // great to defer parsing everything until later.
492    fn inline_table(&mut self) -> Result<(Span, Vec<TablePair<'a>>), Error> {
493        let mut ret = Vec::new();
494        self.eat_whitespace()?;
495        if let Some(span) = self.eat_spanned(Token::RightBrace)? {
496            return Ok((span, ret));
497        }
498        loop {
499            let key = self.dotted_key()?;
500            self.eat_whitespace()?;
501            self.expect(Token::Equals)?;
502            self.eat_whitespace()?;
503            let value = self.value()?;
504            self.add_dotted_key(key, value, &mut ret)?;
505
506            self.eat_whitespace()?;
507            if let Some(span) = self.eat_spanned(Token::RightBrace)? {
508                return Ok((span, ret));
509            }
510            self.expect(Token::Comma)?;
511            self.eat_whitespace()?;
512        }
513    }
514
515    // TODO(#140): shouldn't buffer up this entire array in memory, it'd be
516    // great to defer parsing everything until later.
517    pub fn array(&mut self) -> Result<(Span, Vec<Value<'a>>), Error> {
518        let mut ret = Vec::new();
519
520        let intermediate = |me: &mut Parser<'_>| {
521            loop {
522                me.eat_whitespace()?;
523                if !me.eat(Token::Newline)? && !me.eat_comment()? {
524                    break;
525                }
526            }
527            Ok(())
528        };
529
530        loop {
531            intermediate(self)?;
532            if let Some(span) = self.eat_spanned(Token::RightBracket)? {
533                return Ok((span, ret));
534            }
535            let value = self.value()?;
536            ret.push(value);
537            intermediate(self)?;
538            if !self.eat(Token::Comma)? {
539                break;
540            }
541        }
542        intermediate(self)?;
543        let span = self.expect_spanned(Token::RightBracket)?;
544        Ok((span, ret))
545    }
546
547    fn table_key(&mut self) -> Result<(Span, Cow<'a, str>), Error> {
548        self.tokens.table_key().map_err(|e| self.token_error(e))
549    }
550
551    fn dotted_key(&mut self) -> Result<Vec<(Span, Cow<'a, str>)>, Error> {
552        let mut result = Vec::new();
553        result.push(self.table_key()?);
554        self.eat_whitespace()?;
555        while self.eat(Token::Period)? {
556            self.eat_whitespace()?;
557            result.push(self.table_key()?);
558            self.eat_whitespace()?;
559        }
560        Ok(result)
561    }
562
563    /// Stores a value in the appropriate hierachical structure positioned based on the dotted key.
564    ///
565    /// Given the following definition: `multi.part.key = "value"`, `multi` and `part` are
566    /// intermediate parts which are mapped to the relevant fields in the deserialized type's data
567    /// hierarchy.
568    ///
569    /// # Parameters
570    ///
571    /// * `key_parts`: Each segment of the dotted key, e.g. `part.one` maps to
572    ///                `vec![Cow::Borrowed("part"), Cow::Borrowed("one")].`
573    /// * `value`: The parsed value.
574    /// * `values`: The `Vec` to store the value in.
575    fn add_dotted_key(
576        &self,
577        mut key_parts: Vec<(Span, Cow<'a, str>)>,
578        value: Value<'a>,
579        values: &mut Vec<TablePair<'a>>,
580    ) -> Result<(), Error> {
581        let key = key_parts.remove(0);
582        if key_parts.is_empty() {
583            values.push((key, value));
584            return Ok(());
585        }
586        match values.iter_mut().find(|&&mut (ref k, _)| *k.1 == key.1) {
587            Some(&mut (
588                _,
589                Value {
590                    e: ValueKind::DottedTable(ref mut v),
591                    ..
592                },
593            )) => {
594                return self.add_dotted_key(key_parts, value, v);
595            }
596            Some(&mut (_, Value { start, .. })) => {
597                return Err(self.error(start, ErrorKind::DottedKeyInvalidType));
598            }
599            None => {}
600        }
601        // The start/end value is somewhat misleading here.
602        let table_values = Value {
603            e: ValueKind::DottedTable(Vec::new()),
604            start: value.start,
605            end: value.end,
606        };
607        values.push((key, table_values));
608        let last_i = values.len() - 1;
609        if let (
610            _,
611            Value {
612                e: ValueKind::DottedTable(ref mut v),
613                ..
614            },
615        ) = values[last_i]
616        {
617            self.add_dotted_key(key_parts, value, v)?;
618        }
619        Ok(())
620    }
621
622    fn eat_whitespace(&mut self) -> Result<(), Error> {
623        self.tokens
624            .eat_whitespace()
625            .map_err(|e| self.token_error(e))
626    }
627
628    fn eat_comment(&mut self) -> Result<bool, Error> {
629        self.tokens.eat_comment().map_err(|e| self.token_error(e))
630    }
631
632    fn eat_newline_or_eof(&mut self) -> Result<(), Error> {
633        self.tokens
634            .eat_newline_or_eof()
635            .map_err(|e| self.token_error(e))
636    }
637
638    fn eat(&mut self, expected: Token<'a>) -> Result<bool, Error> {
639        self.tokens.eat(expected).map_err(|e| self.token_error(e))
640    }
641
642    fn eat_spanned(&mut self, expected: Token<'a>) -> Result<Option<Span>, Error> {
643        self.tokens
644            .eat_spanned(expected)
645            .map_err(|e| self.token_error(e))
646    }
647
648    fn expect(&mut self, expected: Token<'a>) -> Result<(), Error> {
649        self.tokens
650            .expect(expected)
651            .map_err(|e| self.token_error(e))
652    }
653
654    fn expect_spanned(&mut self, expected: Token<'a>) -> Result<Span, Error> {
655        self.tokens
656            .expect_spanned(expected)
657            .map_err(|e| self.token_error(e))
658    }
659
660    fn next(&mut self) -> Result<Option<(Span, Token<'a>)>, Error> {
661        self.tokens.next().map_err(|e| self.token_error(e))
662    }
663
664    fn peek(&mut self) -> Result<Option<(Span, Token<'a>)>, Error> {
665        self.tokens.peek().map_err(|e| self.token_error(e))
666    }
667
668    fn eof(&self) -> Error {
669        self.error(self.input.len(), ErrorKind::UnexpectedEof)
670    }
671
672    fn token_error(&self, error: TokenError) -> Error {
673        match error {
674            TokenError::InvalidCharInString(at, ch) => {
675                self.error(at, ErrorKind::InvalidCharInString(ch))
676            }
677            TokenError::InvalidEscape(at, ch) => self.error(at, ErrorKind::InvalidEscape(ch)),
678            TokenError::InvalidEscapeValue(at, v) => {
679                self.error(at, ErrorKind::InvalidEscapeValue(v))
680            }
681            TokenError::InvalidHexEscape(at, ch) => self.error(at, ErrorKind::InvalidHexEscape(ch)),
682            TokenError::NewlineInString(at) => self.error(at, ErrorKind::NewlineInString),
683            TokenError::Unexpected(at, ch) => self.error(at, ErrorKind::Unexpected(ch)),
684            TokenError::UnterminatedString(at) => self.error(at, ErrorKind::UnterminatedString),
685            TokenError::NewlineInTableKey(at) => self.error(at, ErrorKind::NewlineInTableKey),
686            TokenError::Wanted {
687                at,
688                expected,
689                found,
690            } => self.error(at, ErrorKind::Wanted { expected, found }),
691            TokenError::EmptyTableKey(at) => self.error(at, ErrorKind::EmptyTableKey),
692            TokenError::MultilineStringKey(at) => self.error(at, ErrorKind::MultilineStringKey),
693        }
694    }
695
696    fn error(&self, at: usize, kind: ErrorKind) -> Error {
697        let mut err = Error::from_kind(Some(at), kind);
698        err.fix_linecol(|at| self.to_linecol(at));
699        err
700    }
701
702    /// Converts a byte offset from an error message to a (line, column) pair
703    ///
704    /// All indexes are 0-based.
705    fn to_linecol(&self, offset: usize) -> (usize, usize) {
706        let mut cur = 0;
707        // Use split_terminator instead of lines so that if there is a `\r`,
708        // it is included in the offset calculation. The `+1` values below
709        // account for the `\n`.
710        for (i, line) in self.input.split_terminator('\n').enumerate() {
711            if cur + line.len() + 1 > offset {
712                return (i, offset - cur);
713            }
714            cur += line.len() + 1;
715        }
716        (self.input.lines().count(), 0)
717    }
718}
719
720impl Error {
721    /// Produces a (line, column) pair of the position of the error if available
722    ///
723    /// All indexes are 0-based.
724    pub fn line_col(&self) -> Option<(usize, usize)> {
725        self.inner.line.map(|line| (line, self.inner.col))
726    }
727
728    fn from_kind(at: Option<usize>, kind: ErrorKind) -> Error {
729        Error {
730            inner: Box::new(ErrorInner {
731                kind,
732                line: None,
733                col: 0,
734                at,
735                message: String::new(),
736                key: Vec::new(),
737            }),
738        }
739    }
740
741    fn fix_linecol<F>(&mut self, f: F)
742    where
743        F: FnOnce(usize) -> (usize, usize),
744    {
745        if let Some(at) = self.inner.at {
746            let (line, col) = f(at);
747            self.inner.line = Some(line);
748            self.inner.col = col;
749        }
750    }
751}
752
753impl std::convert::From<Error> for std::io::Error {
754    fn from(e: Error) -> Self {
755        std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string())
756    }
757}
758
759impl fmt::Display for Error {
760    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
761        match self.inner.kind {
762            ErrorKind::UnexpectedEof => "unexpected eof encountered".fmt(f)?,
763            ErrorKind::InvalidCharInString(c) => write!(
764                f,
765                "invalid character in string: `{}`",
766                c.escape_default().collect::<String>()
767            )?,
768            ErrorKind::InvalidEscape(c) => write!(
769                f,
770                "invalid escape character in string: `{}`",
771                c.escape_default().collect::<String>()
772            )?,
773            ErrorKind::InvalidHexEscape(c) => write!(
774                f,
775                "invalid hex escape character in string: `{}`",
776                c.escape_default().collect::<String>()
777            )?,
778            ErrorKind::InvalidEscapeValue(c) => write!(f, "invalid escape value: `{}`", c)?,
779            ErrorKind::NewlineInString => "newline in string found".fmt(f)?,
780            ErrorKind::Unexpected(ch) => write!(
781                f,
782                "unexpected character found: `{}`",
783                ch.escape_default().collect::<String>()
784            )?,
785            ErrorKind::UnterminatedString => "unterminated string".fmt(f)?,
786            ErrorKind::NewlineInTableKey => "found newline in table key".fmt(f)?,
787            ErrorKind::Wanted { expected, found } => {
788                write!(f, "expected {}, found {}", expected, found)?
789            }
790            ErrorKind::NumberInvalid => "invalid number".fmt(f)?,
791            ErrorKind::DateInvalid => "invalid date".fmt(f)?,
792            ErrorKind::EmptyTableKey => "empty table key found".fmt(f)?,
793            ErrorKind::MultilineStringKey => "multiline strings are not allowed for key".fmt(f)?,
794            ErrorKind::DottedKeyInvalidType => {
795                "dotted key attempted to extend non-table type".fmt(f)?
796            },
797            ErrorKind::__Nonexhaustive => panic!(),
798        }
799
800        if !self.inner.key.is_empty() {
801            write!(f, " for key `")?;
802            for (i, k) in self.inner.key.iter().enumerate() {
803                if i > 0 {
804                    write!(f, ".")?;
805                }
806                write!(f, "{}", k)?;
807            }
808            write!(f, "`")?;
809        }
810
811        if let Some(line) = self.inner.line {
812            write!(f, " at line {} column {}", line + 1, self.inner.col + 1)?;
813        }
814
815        Ok(())
816    }
817}
818
819impl error::Error for Error {}
820
821pub enum Line<'a> {
822    Table {
823        at: usize,
824        header: Header<'a>,
825        array: bool,
826    },
827    KeyValue(Vec<(Span, Cow<'a, str>)>, Value<'a>),
828}
829
830pub struct Header<'a> {
831    first: bool,
832    pub array: bool,
833    tokens: Tokenizer<'a>,
834}
835
836impl<'a> Header<'a> {
837    fn new(tokens: Tokenizer<'a>, array: bool) -> Header<'a> {
838        Header {
839            first: true,
840            array,
841            tokens,
842        }
843    }
844
845    pub fn next(&mut self) -> Result<Option<(Span, Cow<'a, str>)>, TokenError> {
846        self.tokens.eat_whitespace()?;
847
848        if self.first || self.tokens.eat(Token::Period)? {
849            self.first = false;
850            self.tokens.eat_whitespace()?;
851            self.tokens.table_key().map(|t| t).map(Some)
852        } else {
853            self.tokens.expect(Token::RightBracket)?;
854            if self.array {
855                self.tokens.expect(Token::RightBracket)?;
856            }
857
858            self.tokens.eat_whitespace()?;
859            if !self.tokens.eat_comment()? {
860                self.tokens.eat_newline_or_eof()?;
861            }
862            Ok(None)
863        }
864    }
865}
866
867#[derive(Debug)]
868pub struct Value<'a> {
869    pub e: ValueKind<'a>,
870    start: usize,
871    end: usize,
872}
873
874#[derive(Debug)]
875pub enum ValueKind<'a> {
876    Integer(i64),
877    Float(f64),
878    Boolean(bool),
879    String(Cow<'a, str>),
880    Datetime(&'a str),
881    Array(Vec<Value<'a>>),
882    InlineTable(Vec<TablePair<'a>>),
883    DottedTable(Vec<TablePair<'a>>),
884}
885
886// impl<'a> E<'a> {
887//     fn type_name(&self) -> &'static str {
888//         match *self {
889//             E::String(..) => "string",
890//             E::Integer(..) => "integer",
891//             E::Float(..) => "float",
892//             E::Boolean(..) => "boolean",
893//             E::Datetime(..) => "datetime",
894//             E::Array(..) => "array",
895//             E::InlineTable(..) => "inline table",
896//             E::DottedTable(..) => "dotted table",
897//         }
898//     }
899// }