1 use std::cell::RefCell;
2 #[allow(unused_imports)]
3 use std::ops::DerefMut;
4 
5 use winnow::combinator::cut_err;
6 use winnow::combinator::delimited;
7 use winnow::combinator::peek;
8 use winnow::token::take;
9 
10 // https://github.com/rust-lang/rust/issues/41358
11 use crate::parser::key::key;
12 use crate::parser::prelude::*;
13 use crate::parser::state::ParseState;
14 use crate::parser::trivia::line_trailing;
15 
16 // std-table-open  = %x5B ws     ; [ Left square bracket
17 pub(crate) const STD_TABLE_OPEN: u8 = b'[';
18 // std-table-close = ws %x5D     ; ] Right square bracket
19 const STD_TABLE_CLOSE: u8 = b']';
20 // array-table-open  = %x5B.5B ws  ; [[ Double left square bracket
21 const ARRAY_TABLE_OPEN: &[u8] = b"[[";
22 // array-table-close = ws %x5D.5D  ; ]] Double right quare bracket
23 const ARRAY_TABLE_CLOSE: &[u8] = b"]]";
24 
25 // ;; Standard Table
26 
27 // std-table = std-table-open key *( table-key-sep key) std-table-close
std_table<'s, 'i>( state: &'s RefCell<ParseState>, ) -> impl Parser<Input<'i>, (), ContextError> + 's28 pub(crate) fn std_table<'s, 'i>(
29     state: &'s RefCell<ParseState>,
30 ) -> impl Parser<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
array_table<'s, 'i>( state: &'s RefCell<ParseState>, ) -> impl Parser<Input<'i>, (), ContextError> + 's53 pub(crate) fn array_table<'s, 'i>(
54     state: &'s RefCell<ParseState>,
55 ) -> impl Parser<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
table<'s, 'i>( state: &'s RefCell<ParseState>, ) -> impl Parser<Input<'i>, (), ContextError> + 's78 pub(crate) fn table<'s, 'i>(
79     state: &'s RefCell<ParseState>,
80 ) -> impl Parser<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 }
90