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