toml_span/
de.rs

1//! Core deserialization logic that deserializes toml content to [`Value`]
2
3use crate::{
4    error::{Error, ErrorKind},
5    tokens::{Error as TokenError, Token, Tokenizer},
6    value::{self, Key, Value, ValueInner},
7    Span,
8};
9use smallvec::SmallVec;
10use std::{
11    borrow::Cow,
12    collections::{btree_map::Entry, BTreeMap},
13};
14
15type DeStr<'de> = Cow<'de, str>;
16type TablePair<'de> = (Key<'de>, Val<'de>);
17type InlineVec<T> = SmallVec<[T; 5]>;
18
19/// Parses a toml string into a [`ValueInner::Table`]
20pub fn parse(s: &str) -> Result<Value<'_>, Error> {
21    let mut de = Deserializer::new(s);
22
23    let mut tables = de.tables()?;
24    let table_indices = build_table_indices(&tables);
25    let table_pindices = build_table_pindices(&tables);
26
27    let root_ctx = Ctx {
28        depth: 0,
29        cur: 0,
30        cur_parent: 0,
31        table_indices: &table_indices,
32        table_pindices: &table_pindices,
33        de: &de,
34        values: None,
35        max: tables.len(),
36    };
37
38    let mut root = value::Table::new();
39    deserialize_table(root_ctx, &mut tables, &mut root)?;
40
41    Ok(Value::with_span(
42        ValueInner::Table(root),
43        Span::new(0, s.len()),
44    ))
45}
46
47struct Deserializer<'a> {
48    input: &'a str,
49    tokens: Tokenizer<'a>,
50}
51
52struct Ctx<'de, 'b> {
53    depth: usize,
54    cur: usize,
55    cur_parent: usize,
56    max: usize,
57    table_indices: &'b BTreeMap<InlineVec<DeStr<'de>>, Vec<usize>>,
58    table_pindices: &'b BTreeMap<InlineVec<DeStr<'de>>, Vec<usize>>,
59    de: &'b Deserializer<'de>,
60    values: Option<Vec<TablePair<'de>>>,
61    //array: bool,
62}
63
64impl Ctx<'_, '_> {
65    #[inline]
66    fn error(&self, start: usize, end: Option<usize>, kind: ErrorKind) -> Error {
67        self.de.error(start, end, kind)
68    }
69}
70
71fn deserialize_table<'de, 'b>(
72    mut ctx: Ctx<'de, 'b>,
73    tables: &'b mut [Table<'de>],
74    table: &mut value::Table<'de>,
75) -> Result<usize, Error> {
76    while ctx.cur_parent < ctx.max && ctx.cur < ctx.max {
77        if let Some(values) = ctx.values.take() {
78            for (key, val) in values {
79                table_insert(table, key, val, ctx.de)?;
80            }
81        }
82
83        let next_table = {
84            let prefix_stripped: InlineVec<_> = tables[ctx.cur_parent].header[..ctx.depth]
85                .iter()
86                .map(|v| v.name.clone())
87                .collect::<InlineVec<_>>();
88            ctx.table_pindices
89                .get(&prefix_stripped)
90                .and_then(|entries| {
91                    let start = entries.binary_search(&ctx.cur).unwrap_or_else(|v| v);
92                    if start == entries.len() || entries[start] < ctx.cur {
93                        return None;
94                    }
95                    entries[start..].iter().find_map(|i| {
96                        let i = *i;
97                        (i < ctx.max && tables[i].values.is_some()).then_some(i)
98                    })
99                })
100        };
101
102        let Some(pos) = next_table else {
103            break;
104        };
105
106        ctx.cur = pos;
107
108        // Test to see if we're duplicating our parent's table, and if so
109        // then this is an error in the toml format
110        if ctx.cur_parent != pos {
111            let cur = &tables[pos];
112            let parent = &tables[ctx.cur_parent];
113            if parent.header == cur.header {
114                let name = cur.header.iter().fold(String::new(), |mut s, k| {
115                    if !s.is_empty() {
116                        s.push('.');
117                    }
118                    s.push_str(&k.name);
119                    s
120                });
121
122                let first = Span::new(parent.at, parent.end);
123
124                return Err(ctx.error(
125                    cur.at,
126                    Some(cur.end),
127                    ErrorKind::DuplicateTable { name, first },
128                ));
129            }
130
131            // If we're here we know we should share the same prefix, and if
132            // the longer table was defined first then we want to narrow
133            // down our parent's length if possible to ensure that we catch
134            // duplicate tables defined afterwards.
135            let parent_len = parent.header.len();
136            let cur_len = cur.header.len();
137            if cur_len < parent_len {
138                ctx.cur_parent = pos;
139            }
140        }
141
142        let ttable = &mut tables[pos];
143
144        // If we're not yet at the appropriate depth for this table then we
145        // just next the next portion of its header and then continue
146        // decoding.
147        if ctx.depth != ttable.header.len() {
148            let key = ttable.header[ctx.depth].clone();
149            if let Some((k, _)) = table.get_key_value(&key) {
150                return Err(ctx.error(
151                    key.span.start,
152                    Some(key.span.end),
153                    ErrorKind::DuplicateKey {
154                        key: key.name.to_string(),
155                        first: k.span,
156                    },
157                ));
158            }
159
160            let span = ttable.values.as_ref().and_then(|v| v.span).map_or_else(
161                || Span::new(ttable.at, ttable.end),
162                |span| Span::new(ttable.at.min(span.start), ttable.end.max(span.end)),
163            );
164
165            let array = ttable.array && ctx.depth == ttable.header.len() - 1;
166            ctx.cur += 1;
167
168            let cctx = Ctx {
169                depth: ctx.depth + if array { 0 } else { 1 },
170                max: ctx.max,
171                cur: 0,
172                cur_parent: pos,
173                table_indices: ctx.table_indices,
174                table_pindices: ctx.table_pindices,
175                de: ctx.de,
176                values: None,
177            };
178
179            let value = if array {
180                let mut arr = Vec::new();
181                deserialize_array(cctx, tables, &mut arr)?;
182                ValueInner::Array(arr)
183            } else {
184                let mut tab = value::Table::new();
185                deserialize_table(cctx, tables, &mut tab)?;
186                ValueInner::Table(tab)
187            };
188
189            table.insert(key, Value::with_span(value, span));
190            continue;
191        }
192
193        // Rule out cases like:
194        //
195        //      [[foo.bar]]
196        //      [[foo]]
197        if ttable.array {
198            return Err(ctx.error(ttable.at, Some(ttable.end), ErrorKind::RedefineAsArray));
199        }
200
201        ctx.values = ttable.values.take().map(|table| table.values);
202    }
203
204    Ok(ctx.cur_parent)
205}
206
207fn to_value<'de>(val: Val<'de>, de: &Deserializer<'de>) -> Result<Value<'de>, Error> {
208    let value = match val.e {
209        E::String(s) => ValueInner::String(s),
210        E::Boolean(b) => ValueInner::Boolean(b),
211        E::Integer(i) => ValueInner::Integer(i),
212        E::Float(f) => ValueInner::Float(f),
213        E::Array(arr) => {
214            let mut varr = Vec::new();
215            for val in arr {
216                varr.push(to_value(val, de)?);
217            }
218            ValueInner::Array(varr)
219        }
220        E::DottedTable(tab) | E::InlineTable(tab) => {
221            let mut ntable = value::Table::new();
222
223            for (k, v) in tab.values {
224                table_insert(&mut ntable, k, v, de)?;
225            }
226
227            ValueInner::Table(ntable)
228        }
229    };
230
231    Ok(Value::with_span(value, Span::new(val.start, val.end)))
232}
233
234fn table_insert<'de>(
235    table: &mut value::Table<'de>,
236    key: Key<'de>,
237    val: Val<'de>,
238    de: &Deserializer<'de>,
239) -> Result<(), Error> {
240    match table.entry(key.clone()) {
241        Entry::Occupied(occ) => Err(de.error(
242            key.span.start,
243            Some(key.span.end),
244            ErrorKind::DuplicateKey {
245                key: key.name.to_string(),
246                first: occ.key().span,
247            },
248        )),
249        Entry::Vacant(vac) => {
250            vac.insert(to_value(val, de)?);
251            Ok(())
252        }
253    }
254}
255
256fn deserialize_array<'de, 'b>(
257    mut ctx: Ctx<'de, 'b>,
258    tables: &'b mut [Table<'de>],
259    arr: &mut Vec<value::Value<'de>>,
260) -> Result<usize, Error> {
261    while ctx.cur_parent < ctx.max {
262        let header_stripped = tables[ctx.cur_parent]
263            .header
264            .iter()
265            .map(|v| v.name.clone())
266            .collect::<InlineVec<_>>();
267        let start_idx = ctx.cur_parent + 1;
268        let next = ctx
269            .table_indices
270            .get(&header_stripped)
271            .and_then(|entries| {
272                let start = entries.binary_search(&start_idx).unwrap_or_else(|v| v);
273                if start == entries.len() || entries[start] < start_idx {
274                    return None;
275                }
276                entries[start..]
277                    .iter()
278                    .filter_map(|i| if *i < ctx.max { Some(*i) } else { None })
279                    .map(|i| (i, &tables[i]))
280                    .find(|(_, table)| table.array)
281                    .map(|p| p.0)
282            })
283            .unwrap_or(ctx.max);
284
285        let ttable = &mut tables[ctx.cur_parent];
286
287        let span = ttable.values.as_ref().and_then(|v| v.span).map_or_else(
288            || Span::new(ttable.at, ttable.end),
289            |span| Span::new(ttable.at.min(span.start), ttable.end.max(span.end)),
290        );
291
292        let actx = Ctx {
293            values: Some(ttable.values.take().expect("no array values").values),
294            max: next,
295            depth: ctx.depth + 1,
296            cur: 0,
297            cur_parent: ctx.cur_parent,
298            table_indices: ctx.table_indices,
299            table_pindices: ctx.table_pindices,
300            de: ctx.de,
301        };
302
303        let mut table = value::Table::new();
304        deserialize_table(actx, tables, &mut table)?;
305        arr.push(Value::with_span(ValueInner::Table(table), span));
306
307        ctx.cur_parent = next;
308    }
309
310    Ok(ctx.cur_parent)
311}
312
313// Builds a datastructure that allows for efficient sublinear lookups. The
314// returned BTreeMap contains a mapping from table header (like [a.b.c]) to list
315// of tables with that precise name. The tables are being identified by their
316// index in the passed slice. We use a list as the implementation uses this data
317// structure for arrays as well as tables, so if any top level [[name]] array
318// contains multiple entries, there are multiple entries in the list. The lookup
319// is performed in the `SeqAccess` implementation of `MapVisitor`. The lists are
320// ordered, which we exploit in the search code by using bisection.
321fn build_table_indices<'de>(tables: &[Table<'de>]) -> BTreeMap<InlineVec<DeStr<'de>>, Vec<usize>> {
322    let mut res = BTreeMap::new();
323    for (i, table) in tables.iter().enumerate() {
324        let header = table
325            .header
326            .iter()
327            .map(|v| v.name.clone())
328            .collect::<InlineVec<_>>();
329        res.entry(header).or_insert_with(Vec::new).push(i);
330    }
331    res
332}
333
334// Builds a datastructure that allows for efficient sublinear lookups. The
335// returned BTreeMap contains a mapping from table header (like [a.b.c]) to list
336// of tables whose name at least starts with the specified name. So searching
337// for [a.b] would give both [a.b.c.d] as well as [a.b.e]. The tables are being
338// identified by their index in the passed slice.
339//
340// A list is used for two reasons: First, the implementation also stores arrays
341// in the same data structure and any top level array of size 2 or greater
342// creates multiple entries in the list with the same shared name. Second, there
343// can be multiple tables sharing the same prefix.
344//
345// The lookup is performed in the `MapAccess` implementation of `MapVisitor`.
346// The lists are ordered, which we exploit in the search code by using
347// bisection.
348fn build_table_pindices<'de>(tables: &[Table<'de>]) -> BTreeMap<InlineVec<DeStr<'de>>, Vec<usize>> {
349    let mut res = BTreeMap::new();
350    for (i, table) in tables.iter().enumerate() {
351        let header = table
352            .header
353            .iter()
354            .map(|v| v.name.clone())
355            .collect::<InlineVec<_>>();
356        for len in 0..=header.len() {
357            res.entry(header[..len].into())
358                .or_insert_with(Vec::new)
359                .push(i);
360        }
361    }
362    res
363}
364
365struct Table<'de> {
366    at: usize,
367    end: usize,
368    header: InlineVec<Key<'de>>,
369    values: Option<TableValues<'de>>,
370    array: bool,
371}
372
373struct TableValues<'de> {
374    values: Vec<TablePair<'de>>,
375    span: Option<Span>,
376}
377
378#[allow(clippy::derivable_impls)]
379impl Default for TableValues<'_> {
380    fn default() -> Self {
381        Self {
382            values: Vec::new(),
383            span: None,
384        }
385    }
386}
387
388impl<'a> Deserializer<'a> {
389    fn new(input: &'a str) -> Deserializer<'a> {
390        Deserializer {
391            tokens: Tokenizer::new(input),
392            input,
393        }
394    }
395
396    fn tables(&mut self) -> Result<Vec<Table<'a>>, Error> {
397        let mut tables = Vec::new();
398        let mut cur_table = Table {
399            at: 0,
400            end: 0,
401            header: InlineVec::new(),
402            values: None,
403            array: false,
404        };
405
406        while let Some(line) = self.line()? {
407            match line {
408                Line::Table {
409                    at,
410                    end,
411                    mut header,
412                    array,
413                } => {
414                    if !cur_table.header.is_empty() || cur_table.values.is_some() {
415                        tables.push(cur_table);
416                    }
417                    cur_table = Table {
418                        at,
419                        end,
420                        header: InlineVec::new(),
421                        values: Some(TableValues::default()),
422                        array,
423                    };
424                    while let Some(part) = header.next().map_err(|e| self.token_error(e))? {
425                        cur_table.header.push(part);
426                    }
427                    cur_table.end = header.tokens.current();
428                }
429                Line::KeyValue {
430                    key,
431                    value,
432                    at,
433                    end,
434                } => {
435                    let table_values = cur_table.values.get_or_insert_with(|| TableValues {
436                        values: Vec::new(),
437                        span: None,
438                    });
439                    self.add_dotted_key(key, value, table_values)?;
440                    match table_values.span {
441                        Some(ref mut span) => {
442                            span.start = span.start.min(at);
443                            span.end = span.end.max(end);
444                        }
445                        None => {
446                            table_values.span = Some(Span::new(at, end));
447                        }
448                    }
449                }
450            }
451        }
452        if !cur_table.header.is_empty() || cur_table.values.is_some() {
453            tables.push(cur_table);
454        }
455        Ok(tables)
456    }
457
458    fn line(&mut self) -> Result<Option<Line<'a>>, Error> {
459        loop {
460            self.eat_whitespace();
461            if self.eat_comment()? {
462                continue;
463            }
464            if self.eat(Token::Newline)? {
465                continue;
466            }
467            break;
468        }
469
470        match self.peek()? {
471            Some((_, Token::LeftBracket)) => self.table_header().map(Some),
472            Some(_) => self.key_value().map(Some),
473            None => Ok(None),
474        }
475    }
476
477    fn table_header(&mut self) -> Result<Line<'a>, Error> {
478        let start = self.tokens.current();
479        self.expect(Token::LeftBracket)?;
480        let array = self.eat(Token::LeftBracket)?;
481        let ret = Header::new(self.tokens.clone(), array);
482        self.tokens.skip_to_newline();
483        let end = self.tokens.current();
484        Ok(Line::Table {
485            at: start,
486            end,
487            header: ret,
488            array,
489        })
490    }
491
492    fn key_value(&mut self) -> Result<Line<'a>, Error> {
493        let start = self.tokens.current();
494        let key = self.dotted_key()?;
495        self.eat_whitespace();
496        self.expect(Token::Equals)?;
497        self.eat_whitespace();
498
499        let value = self.value()?;
500        let end = self.tokens.current();
501        self.eat_whitespace();
502        if !self.eat_comment()? {
503            self.eat_newline_or_eof()?;
504        }
505
506        Ok(Line::KeyValue {
507            key,
508            value,
509            at: start,
510            end,
511        })
512    }
513
514    fn value(&mut self) -> Result<Val<'a>, Error> {
515        let at = self.tokens.current();
516        let value = match self.next()? {
517            Some((Span { start, end }, Token::String { val, .. })) => Val {
518                e: E::String(val),
519                start,
520                end,
521            },
522            Some((Span { start, end }, Token::Keylike("true"))) => Val {
523                e: E::Boolean(true),
524                start,
525                end,
526            },
527            Some((Span { start, end }, Token::Keylike("false"))) => Val {
528                e: E::Boolean(false),
529                start,
530                end,
531            },
532            Some((span, Token::Keylike(key))) => self.parse_keylike(at, span, key)?,
533            Some((span, Token::Plus)) => self.number_leading_plus(span)?,
534            Some((Span { start, .. }, Token::LeftBrace)) => {
535                self.inline_table().map(|(Span { end, .. }, table)| Val {
536                    e: E::InlineTable(table),
537                    start,
538                    end,
539                })?
540            }
541            Some((Span { start, .. }, Token::LeftBracket)) => {
542                self.array().map(|(Span { end, .. }, array)| Val {
543                    e: E::Array(array),
544                    start,
545                    end,
546                })?
547            }
548            Some(token) => {
549                return Err(self.error(
550                    at,
551                    Some(token.0.end),
552                    ErrorKind::Wanted {
553                        expected: "a value",
554                        found: token.1.describe(),
555                    },
556                ));
557            }
558            None => return Err(self.eof()),
559        };
560        Ok(value)
561    }
562
563    fn parse_keylike(&mut self, at: usize, span: Span, key: &'a str) -> Result<Val<'a>, Error> {
564        if key == "inf" || key == "nan" {
565            return self.number(span, key);
566        }
567
568        let first_char = key.chars().next().expect("key should not be empty here");
569        match first_char {
570            '-' | '0'..='9' => self.number(span, key),
571            _ => Err(self.error(at, Some(span.end), ErrorKind::UnquotedString)),
572        }
573    }
574
575    fn number(&mut self, Span { start, end }: Span, s: &'a str) -> Result<Val<'a>, Error> {
576        let to_integer = |f| Val {
577            e: E::Integer(f),
578            start,
579            end,
580        };
581        if let Some(s) = s.strip_prefix("0x") {
582            self.integer(s, 16).map(to_integer)
583        } else if let Some(s) = s.strip_prefix("0o") {
584            self.integer(s, 8).map(to_integer)
585        } else if let Some(s) = s.strip_prefix("0b") {
586            self.integer(s, 2).map(to_integer)
587        } else if s.contains('e') || s.contains('E') {
588            self.float(s, None).map(|f| Val {
589                e: E::Float(f),
590                start,
591                end: self.tokens.current(),
592            })
593        } else if self.eat(Token::Period)? {
594            let at = self.tokens.current();
595            match self.next()? {
596                Some((Span { .. }, Token::Keylike(after))) => {
597                    self.float(s, Some(after)).map(|f| Val {
598                        e: E::Float(f),
599                        start,
600                        end: self.tokens.current(),
601                    })
602                }
603                _ => Err(self.error(at, Some(end), ErrorKind::InvalidNumber)),
604            }
605        } else if s == "inf" {
606            Ok(Val {
607                e: E::Float(f64::INFINITY),
608                start,
609                end,
610            })
611        } else if s == "-inf" {
612            Ok(Val {
613                e: E::Float(f64::NEG_INFINITY),
614                start,
615                end,
616            })
617        } else if s == "nan" {
618            Ok(Val {
619                e: E::Float(f64::NAN.copysign(1.0)),
620                start,
621                end,
622            })
623        } else if s == "-nan" {
624            Ok(Val {
625                e: E::Float(f64::NAN.copysign(-1.0)),
626                start,
627                end,
628            })
629        } else {
630            self.integer(s, 10).map(to_integer)
631        }
632    }
633
634    fn number_leading_plus(&mut self, Span { start, end }: Span) -> Result<Val<'a>, Error> {
635        let start_token = self.tokens.current();
636        match self.next()? {
637            Some((Span { end, .. }, Token::Keylike(s))) => self.number(Span { start, end }, s),
638            _ => Err(self.error(start_token, Some(end), ErrorKind::InvalidNumber)),
639        }
640    }
641
642    fn integer(&self, s: &'a str, radix: u32) -> Result<i64, Error> {
643        let allow_sign = radix == 10;
644        let allow_leading_zeros = radix != 10;
645        let (prefix, suffix) = self.parse_integer(s, allow_sign, allow_leading_zeros, radix)?;
646        let start = self.tokens.substr_offset(s);
647        if !suffix.is_empty() {
648            return Err(self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber));
649        }
650        i64::from_str_radix(prefix.replace('_', "").trim_start_matches('+'), radix)
651            .map_err(|_e| self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber))
652    }
653
654    fn parse_integer(
655        &self,
656        s: &'a str,
657        allow_sign: bool,
658        allow_leading_zeros: bool,
659        radix: u32,
660    ) -> Result<(&'a str, &'a str), Error> {
661        let start = self.tokens.substr_offset(s);
662
663        let mut first = true;
664        let mut first_zero = false;
665        let mut underscore = false;
666        let mut end = s.len();
667        let send = start + s.len();
668        for (i, c) in s.char_indices() {
669            let at = i + start;
670            if i == 0 && (c == '+' || c == '-') && allow_sign {
671                continue;
672            }
673
674            if c == '0' && first {
675                first_zero = true;
676            } else if c.is_digit(radix) {
677                if !first && first_zero && !allow_leading_zeros {
678                    return Err(self.error(at, Some(send), ErrorKind::InvalidNumber));
679                }
680                underscore = false;
681            } else if c == '_' && first {
682                return Err(self.error(at, Some(send), ErrorKind::InvalidNumber));
683            } else if c == '_' && !underscore {
684                underscore = true;
685            } else {
686                end = i;
687                break;
688            }
689            first = false;
690        }
691        if first || underscore {
692            return Err(self.error(start, Some(send), ErrorKind::InvalidNumber));
693        }
694        Ok((&s[..end], &s[end..]))
695    }
696
697    fn float(&mut self, s: &'a str, after_decimal: Option<&'a str>) -> Result<f64, Error> {
698        let (integral, mut suffix) = self.parse_integer(s, true, false, 10)?;
699        let start = self.tokens.substr_offset(integral);
700
701        let mut fraction = None;
702        if let Some(after) = after_decimal {
703            if !suffix.is_empty() {
704                return Err(self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber));
705            }
706            let (a, b) = self.parse_integer(after, false, true, 10)?;
707            fraction = Some(a);
708            suffix = b;
709        }
710
711        let mut exponent = None;
712        if suffix.starts_with('e') || suffix.starts_with('E') {
713            let (a, b) = if suffix.len() == 1 {
714                self.eat(Token::Plus)?;
715                match self.next()? {
716                    Some((_, Token::Keylike(s))) => self.parse_integer(s, false, true, 10)?,
717                    _ => {
718                        return Err(self.error(
719                            start,
720                            Some(start + s.len()),
721                            ErrorKind::InvalidNumber,
722                        ))
723                    }
724                }
725            } else {
726                self.parse_integer(&suffix[1..], true, true, 10)?
727            };
728            if !b.is_empty() {
729                return Err(self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber));
730            }
731            exponent = Some(a);
732        } else if !suffix.is_empty() {
733            return Err(self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber));
734        }
735
736        let mut number = integral
737            .trim_start_matches('+')
738            .chars()
739            .filter(|c| *c != '_')
740            .collect::<String>();
741        if let Some(fraction) = fraction {
742            number.push('.');
743            number.extend(fraction.chars().filter(|c| *c != '_'));
744        }
745        if let Some(exponent) = exponent {
746            number.push('E');
747            number.extend(exponent.chars().filter(|c| *c != '_'));
748        }
749        number
750            .parse()
751            .map_err(|_e| self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber))
752            .and_then(|n: f64| {
753                if n.is_finite() {
754                    Ok(n)
755                } else {
756                    Err(self.error(start, Some(start + s.len()), ErrorKind::InvalidNumber))
757                }
758            })
759    }
760
761    // TODO(#140): shouldn't buffer up this entire table in memory, it'd be
762    // great to defer parsing everything until later.
763    fn inline_table(&mut self) -> Result<(Span, TableValues<'a>), Error> {
764        let mut ret = TableValues::default();
765        self.eat_whitespace();
766        if let Some(span) = self.eat_spanned(Token::RightBrace)? {
767            return Ok((span, ret));
768        }
769        loop {
770            let key = self.dotted_key()?;
771            self.eat_whitespace();
772            self.expect(Token::Equals)?;
773            self.eat_whitespace();
774            let value = self.value()?;
775            self.add_dotted_key(key, value, &mut ret)?;
776
777            self.eat_whitespace();
778            if let Some(span) = self.eat_spanned(Token::RightBrace)? {
779                return Ok((span, ret));
780            }
781            self.expect(Token::Comma)?;
782            self.eat_whitespace();
783        }
784    }
785
786    // TODO(#140): shouldn't buffer up this entire array in memory, it'd be
787    // great to defer parsing everything until later.
788    fn array(&mut self) -> Result<(Span, Vec<Val<'a>>), Error> {
789        let mut ret = Vec::new();
790
791        let intermediate = |me: &mut Deserializer<'_>| -> Result<(), Error> {
792            loop {
793                me.eat_whitespace();
794                if !me.eat(Token::Newline)? && !me.eat_comment()? {
795                    break;
796                }
797            }
798            Ok(())
799        };
800
801        loop {
802            intermediate(self)?;
803            if let Some(span) = self.eat_spanned(Token::RightBracket)? {
804                return Ok((span, ret));
805            }
806            let value = self.value()?;
807            ret.push(value);
808            intermediate(self)?;
809            if !self.eat(Token::Comma)? {
810                break;
811            }
812        }
813        intermediate(self)?;
814        let span = self.expect_spanned(Token::RightBracket)?;
815        Ok((span, ret))
816    }
817
818    fn table_key(&mut self) -> Result<Key<'a>, Error> {
819        self.tokens.table_key().map_err(|e| self.token_error(e))
820    }
821
822    fn dotted_key(&mut self) -> Result<Vec<Key<'a>>, Error> {
823        let mut result = Vec::new();
824        result.push(self.table_key()?);
825        self.eat_whitespace();
826        while self.eat(Token::Period)? {
827            self.eat_whitespace();
828            result.push(self.table_key()?);
829            self.eat_whitespace();
830        }
831        Ok(result)
832    }
833
834    /// Stores a value in the appropriate hierarchical structure positioned based on the dotted key.
835    ///
836    /// Given the following definition: `multi.part.key = "value"`, `multi` and `part` are
837    /// intermediate parts which are mapped to the relevant fields in the deserialized type's data
838    /// hierarchy.
839    ///
840    /// # Parameters
841    ///
842    /// * `key_parts`: Each segment of the dotted key, e.g. `part.one` maps to
843    ///                `vec![Cow::Borrowed("part"), Cow::Borrowed("one")].`
844    /// * `value`: The parsed value.
845    /// * `values`: The `Vec` to store the value in.
846    fn add_dotted_key(
847        &self,
848        mut key_parts: Vec<Key<'a>>,
849        value: Val<'a>,
850        values: &mut TableValues<'a>,
851    ) -> Result<(), Error> {
852        let key = key_parts.remove(0);
853        if key_parts.is_empty() {
854            values.values.push((key, value));
855            return Ok(());
856        }
857        match values
858            .values
859            .iter_mut()
860            .find(|&&mut (ref k, _)| k.name == key.name)
861        {
862            Some(&mut (
863                _,
864                Val {
865                    e: E::DottedTable(ref mut v),
866                    ..
867                },
868            )) => {
869                return self.add_dotted_key(key_parts, value, v);
870            }
871            Some(&mut (ref first, _)) => {
872                return Err(self.error(
873                    key.span.start,
874                    Some(value.end),
875                    ErrorKind::DottedKeyInvalidType { first: first.span },
876                ));
877            }
878            None => {}
879        }
880        // The start/end value is somewhat misleading here.
881        let table_values = Val {
882            e: E::DottedTable(TableValues::default()),
883            start: value.start,
884            end: value.end,
885        };
886        values.values.push((key, table_values));
887        let last_i = values.values.len() - 1;
888        if let (
889            _,
890            Val {
891                e: E::DottedTable(ref mut v),
892                ..
893            },
894        ) = values.values[last_i]
895        {
896            self.add_dotted_key(key_parts, value, v)?;
897        }
898        Ok(())
899    }
900
901    fn eat_whitespace(&mut self) {
902        self.tokens.eat_whitespace();
903    }
904
905    fn eat_comment(&mut self) -> Result<bool, Error> {
906        self.tokens.eat_comment().map_err(|e| self.token_error(e))
907    }
908
909    fn eat_newline_or_eof(&mut self) -> Result<(), Error> {
910        self.tokens
911            .eat_newline_or_eof()
912            .map_err(|e| self.token_error(e))
913    }
914
915    fn eat(&mut self, expected: Token<'a>) -> Result<bool, Error> {
916        self.tokens.eat(expected).map_err(|e| self.token_error(e))
917    }
918
919    fn eat_spanned(&mut self, expected: Token<'a>) -> Result<Option<Span>, Error> {
920        self.tokens
921            .eat_spanned(expected)
922            .map_err(|e| self.token_error(e))
923    }
924
925    fn expect(&mut self, expected: Token<'a>) -> Result<(), Error> {
926        self.tokens
927            .expect(expected)
928            .map_err(|e| self.token_error(e))
929    }
930
931    fn expect_spanned(&mut self, expected: Token<'a>) -> Result<Span, Error> {
932        self.tokens
933            .expect_spanned(expected)
934            .map_err(|e| self.token_error(e))
935    }
936
937    fn next(&mut self) -> Result<Option<(Span, Token<'a>)>, Error> {
938        self.tokens.step().map_err(|e| self.token_error(e))
939    }
940
941    fn peek(&mut self) -> Result<Option<(Span, Token<'a>)>, Error> {
942        self.tokens.peek().map_err(|e| self.token_error(e))
943    }
944
945    fn eof(&self) -> Error {
946        self.error(self.input.len(), None, ErrorKind::UnexpectedEof)
947    }
948
949    fn token_error(&self, error: TokenError) -> Error {
950        match error {
951            TokenError::InvalidCharInString(at, ch) => {
952                self.error(at, None, ErrorKind::InvalidCharInString(ch))
953            }
954            TokenError::InvalidEscape(at, ch) => self.error(at, None, ErrorKind::InvalidEscape(ch)),
955            TokenError::InvalidEscapeValue(at, len, v) => {
956                self.error(at, Some(at + len), ErrorKind::InvalidEscapeValue(v))
957            }
958            TokenError::InvalidHexEscape(at, ch) => {
959                self.error(at, None, ErrorKind::InvalidHexEscape(ch))
960            }
961            TokenError::NewlineInString(at) => {
962                self.error(at, None, ErrorKind::InvalidCharInString('\n'))
963            }
964            TokenError::Unexpected(at, ch) => self.error(at, None, ErrorKind::Unexpected(ch)),
965            TokenError::UnterminatedString(at) => {
966                self.error(at, None, ErrorKind::UnterminatedString)
967            }
968            TokenError::Wanted {
969                at,
970                expected,
971                found,
972            } => self.error(
973                at,
974                Some(at + found.len()),
975                ErrorKind::Wanted { expected, found },
976            ),
977            TokenError::MultilineStringKey(at, end) => {
978                self.error(at, Some(end), ErrorKind::MultilineStringKey)
979            }
980        }
981    }
982
983    fn error(&self, start: usize, end: Option<usize>, kind: ErrorKind) -> Error {
984        let span = Span::new(start, end.unwrap_or(start + 1));
985        let line_info = Some(self.to_linecol(start));
986        Error {
987            span,
988            kind,
989            line_info,
990        }
991    }
992
993    /// Converts a byte offset from an error message to a (line, column) pair
994    ///
995    /// All indexes are 0-based.
996    fn to_linecol(&self, offset: usize) -> (usize, usize) {
997        let mut cur = 0;
998        // Use split_terminator instead of lines so that if there is a `\r`, it
999        // is included in the offset calculation. The `+1` values below account
1000        // for the `\n`.
1001        for (i, line) in self.input.split_terminator('\n').enumerate() {
1002            if cur + line.len() + 1 > offset {
1003                return (i, offset - cur);
1004            }
1005            cur += line.len() + 1;
1006        }
1007        (self.input.lines().count(), 0)
1008    }
1009}
1010
1011impl std::convert::From<Error> for std::io::Error {
1012    fn from(e: Error) -> Self {
1013        std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string())
1014    }
1015}
1016
1017enum Line<'a> {
1018    Table {
1019        at: usize,
1020        end: usize,
1021        header: Header<'a>,
1022        array: bool,
1023    },
1024    KeyValue {
1025        at: usize,
1026        end: usize,
1027        key: Vec<Key<'a>>,
1028        value: Val<'a>,
1029    },
1030}
1031
1032struct Header<'a> {
1033    first: bool,
1034    array: bool,
1035    tokens: Tokenizer<'a>,
1036}
1037
1038impl<'a> Header<'a> {
1039    fn new(tokens: Tokenizer<'a>, array: bool) -> Header<'a> {
1040        Header {
1041            first: true,
1042            array,
1043            tokens,
1044        }
1045    }
1046
1047    fn next(&mut self) -> Result<Option<Key<'a>>, TokenError> {
1048        self.tokens.eat_whitespace();
1049
1050        if self.first || self.tokens.eat(Token::Period)? {
1051            self.first = false;
1052            self.tokens.eat_whitespace();
1053            self.tokens.table_key().map(Some)
1054        } else {
1055            self.tokens.expect(Token::RightBracket)?;
1056            if self.array {
1057                self.tokens.expect(Token::RightBracket)?;
1058            }
1059
1060            self.tokens.eat_whitespace();
1061            if !self.tokens.eat_comment()? {
1062                self.tokens.eat_newline_or_eof()?;
1063            }
1064            Ok(None)
1065        }
1066    }
1067}
1068
1069struct Val<'a> {
1070    e: E<'a>,
1071    start: usize,
1072    end: usize,
1073}
1074
1075enum E<'a> {
1076    Integer(i64),
1077    Float(f64),
1078    Boolean(bool),
1079    String(DeStr<'a>),
1080    Array(Vec<Val<'a>>),
1081    InlineTable(TableValues<'a>),
1082    DottedTable(TableValues<'a>),
1083}
1084
1085impl E<'_> {
1086    #[allow(dead_code)]
1087    fn type_name(&self) -> &'static str {
1088        match *self {
1089            E::String(..) => "string",
1090            E::Integer(..) => "integer",
1091            E::Float(..) => "float",
1092            E::Boolean(..) => "boolean",
1093            E::Array(..) => "array",
1094            E::InlineTable(..) => "inline table",
1095            E::DottedTable(..) => "dotted table",
1096        }
1097    }
1098}