| use std::cell::RefCell; |
| #[allow(unused_imports)] |
| use std::ops::DerefMut; |
| |
| use winnow::combinator::cut_err; |
| use winnow::combinator::delimited; |
| use winnow::combinator::peek; |
| use winnow::token::take; |
| |
| // https://github.com/rust-lang/rust/issues/41358 |
| use crate::parser::key::key; |
| use crate::parser::prelude::*; |
| use crate::parser::state::ParseState; |
| use crate::parser::trivia::line_trailing; |
| |
| // std-table-open = %x5B ws ; [ Left square bracket |
| pub(crate) const STD_TABLE_OPEN: u8 = b'['; |
| // std-table-close = ws %x5D ; ] Right square bracket |
| const STD_TABLE_CLOSE: u8 = b']'; |
| // array-table-open = %x5B.5B ws ; [[ Double left square bracket |
| const ARRAY_TABLE_OPEN: &[u8] = b"[["; |
| // array-table-close = ws %x5D.5D ; ]] Double right quare bracket |
| const ARRAY_TABLE_CLOSE: &[u8] = b"]]"; |
| |
| // ;; Standard Table |
| |
| // std-table = std-table-open key *( table-key-sep key) std-table-close |
| pub(crate) fn std_table<'s, 'i>( |
| state: &'s RefCell<ParseState>, |
| ) -> impl Parser<Input<'i>, (), ContextError> + 's { |
| move |i: &mut Input<'i>| { |
| ( |
| delimited( |
| STD_TABLE_OPEN, |
| cut_err(key), |
| cut_err(STD_TABLE_CLOSE) |
| .context(StrContext::Expected(StrContextValue::CharLiteral('.'))) |
| .context(StrContext::Expected(StrContextValue::StringLiteral("]"))), |
| ) |
| .with_span(), |
| cut_err(line_trailing) |
| .context(StrContext::Expected(StrContextValue::CharLiteral('\n'))) |
| .context(StrContext::Expected(StrContextValue::CharLiteral('#'))), |
| ) |
| .try_map(|((h, span), t)| state.borrow_mut().deref_mut().on_std_header(h, t, span)) |
| .parse_next(i) |
| } |
| } |
| |
| // ;; Array Table |
| |
| // array-table = array-table-open key *( table-key-sep key) array-table-close |
| pub(crate) fn array_table<'s, 'i>( |
| state: &'s RefCell<ParseState>, |
| ) -> impl Parser<Input<'i>, (), ContextError> + 's { |
| move |i: &mut Input<'i>| { |
| ( |
| delimited( |
| ARRAY_TABLE_OPEN, |
| cut_err(key), |
| cut_err(ARRAY_TABLE_CLOSE) |
| .context(StrContext::Expected(StrContextValue::CharLiteral('.'))) |
| .context(StrContext::Expected(StrContextValue::StringLiteral("]]"))), |
| ) |
| .with_span(), |
| cut_err(line_trailing) |
| .context(StrContext::Expected(StrContextValue::CharLiteral('\n'))) |
| .context(StrContext::Expected(StrContextValue::CharLiteral('#'))), |
| ) |
| .try_map(|((h, span), t)| state.borrow_mut().deref_mut().on_array_header(h, t, span)) |
| .parse_next(i) |
| } |
| } |
| |
| // ;; Table |
| |
| // table = std-table / array-table |
| pub(crate) fn table<'s, 'i>( |
| state: &'s RefCell<ParseState>, |
| ) -> impl Parser<Input<'i>, (), ContextError> + 's { |
| move |i: &mut Input<'i>| { |
| dispatch!(peek::<_, &[u8],_,_>(take(2usize)); |
| b"[[" => array_table(state), |
| _ => std_table(state), |
| ) |
| .context(StrContext::Label("table header")) |
| .parse_next(i) |
| } |
| } |