toml_edit/parser/
table.rs

1use std::cell::RefCell;
2#[allow(unused_imports)]
3use std::ops::DerefMut;
4
5use winnow::combinator::cut_err;
6use winnow::combinator::delimited;
7use winnow::combinator::peek;
8use winnow::token::take;
9
10// https://github.com/rust-lang/rust/issues/41358
11use crate::parser::key::key;
12use crate::parser::prelude::*;
13use crate::parser::state::ParseState;
14use crate::parser::trivia::line_trailing;
15
16// std-table-open  = %x5B ws     ; [ Left square bracket
17pub(crate) const STD_TABLE_OPEN: u8 = b'[';
18// std-table-close = ws %x5D     ; ] Right square bracket
19const STD_TABLE_CLOSE: u8 = b']';
20// array-table-open  = %x5B.5B ws  ; [[ Double left square bracket
21const ARRAY_TABLE_OPEN: &[u8] = b"[[";
22// array-table-close = ws %x5D.5D  ; ]] Double right quare bracket
23const ARRAY_TABLE_CLOSE: &[u8] = b"]]";
24
25// ;; Standard Table
26
27// std-table = std-table-open key *( table-key-sep key) std-table-close
28pub(crate) fn std_table<'s, 'i>(
29    state: &'s RefCell<ParseState>,
30) -> impl ModalParser<Input<'i>, (), ContextError> + 's {
31    move |i: &mut Input<'i>| {
32        (
33            delimited(
34                STD_TABLE_OPEN,
35                cut_err(key),
36                cut_err(STD_TABLE_CLOSE)
37                    .context(StrContext::Expected(StrContextValue::CharLiteral('.')))
38                    .context(StrContext::Expected(StrContextValue::StringLiteral("]"))),
39            )
40            .with_span(),
41            cut_err(line_trailing)
42                .context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
43                .context(StrContext::Expected(StrContextValue::CharLiteral('#'))),
44        )
45            .try_map(|((h, span), t)| state.borrow_mut().deref_mut().on_std_header(h, t, span))
46            .parse_next(i)
47    }
48}
49
50// ;; Array Table
51
52// array-table = array-table-open key *( table-key-sep key) array-table-close
53pub(crate) fn array_table<'s, 'i>(
54    state: &'s RefCell<ParseState>,
55) -> impl ModalParser<Input<'i>, (), ContextError> + 's {
56    move |i: &mut Input<'i>| {
57        (
58            delimited(
59                ARRAY_TABLE_OPEN,
60                cut_err(key),
61                cut_err(ARRAY_TABLE_CLOSE)
62                    .context(StrContext::Expected(StrContextValue::CharLiteral('.')))
63                    .context(StrContext::Expected(StrContextValue::StringLiteral("]]"))),
64            )
65            .with_span(),
66            cut_err(line_trailing)
67                .context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
68                .context(StrContext::Expected(StrContextValue::CharLiteral('#'))),
69        )
70            .try_map(|((h, span), t)| state.borrow_mut().deref_mut().on_array_header(h, t, span))
71            .parse_next(i)
72    }
73}
74
75// ;; Table
76
77// table = std-table / array-table
78pub(crate) fn table<'s, 'i>(
79    state: &'s RefCell<ParseState>,
80) -> impl ModalParser<Input<'i>, (), ContextError> + 's {
81    move |i: &mut Input<'i>| {
82        dispatch!(peek::<_, &[u8],_,_>(take(2usize));
83            b"[[" => array_table(state),
84            _ => std_table(state),
85        )
86        .context(StrContext::Label("table header"))
87        .parse_next(i)
88    }
89}