summaryrefslogtreecommitdiffstats
path: root/vendor/toml_edit/src/parser/document.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/toml_edit/src/parser/document.rs')
-rw-r--r--vendor/toml_edit/src/parser/document.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/vendor/toml_edit/src/parser/document.rs b/vendor/toml_edit/src/parser/document.rs
new file mode 100644
index 000000000..38e9e0eee
--- /dev/null
+++ b/vendor/toml_edit/src/parser/document.rs
@@ -0,0 +1,147 @@
+use std::cell::RefCell;
+
+use nom8::bytes::any;
+use nom8::bytes::one_of;
+use nom8::combinator::cut;
+use nom8::combinator::eof;
+use nom8::combinator::opt;
+use nom8::combinator::peek;
+use nom8::error::FromExternalError;
+use nom8::multi::many0_count;
+
+use crate::document::Document;
+use crate::key::Key;
+use crate::parser::inline_table::KEYVAL_SEP;
+use crate::parser::key::key;
+use crate::parser::prelude::*;
+use crate::parser::state::ParseState;
+use crate::parser::table::table;
+use crate::parser::trivia::{comment, line_ending, line_trailing, newline, ws};
+use crate::parser::value::value;
+use crate::table::TableKeyValue;
+use crate::Item;
+use crate::RawString;
+
+// ;; TOML
+
+// toml = expression *( newline expression )
+
+// expression = ( ( ws comment ) /
+// ( ws keyval ws [ comment ] ) /
+// ( ws table ws [ comment ] ) /
+// ws )
+pub(crate) fn document(input: Input<'_>) -> IResult<Input<'_>, Document, ParserError<'_>> {
+ let state = RefCell::new(ParseState::default());
+ let state_ref = &state;
+
+ let (i, _o) = (
+ // Remove BOM if present
+ opt(b"\xEF\xBB\xBF"),
+ parse_ws(state_ref),
+ many0_count((
+ dispatch! {peek(any);
+ crate::parser::trivia::COMMENT_START_SYMBOL => cut(parse_comment(state_ref)),
+ crate::parser::table::STD_TABLE_OPEN => cut(table(state_ref)),
+ crate::parser::trivia::LF |
+ crate::parser::trivia::CR => parse_newline(state_ref),
+ _ => cut(keyval(state_ref)),
+ },
+ parse_ws(state_ref),
+ )),
+ eof,
+ )
+ .parse(input)?;
+ state
+ .into_inner()
+ .into_document()
+ .map(|document| (i, document))
+ .map_err(|err| {
+ nom8::Err::Error(ParserError::from_external_error(
+ i,
+ nom8::error::ErrorKind::MapRes,
+ err,
+ ))
+ })
+}
+
+pub(crate) fn parse_comment<'s, 'i>(
+ state: &'s RefCell<ParseState>,
+) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'_>> + 's {
+ move |i| {
+ (comment, line_ending)
+ .span()
+ .map(|span| {
+ state.borrow_mut().on_comment(span);
+ })
+ .parse(i)
+ }
+}
+
+pub(crate) fn parse_ws<'s, 'i>(
+ state: &'s RefCell<ParseState>,
+) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's {
+ move |i| {
+ ws.span()
+ .map(|span| state.borrow_mut().on_ws(span))
+ .parse(i)
+ }
+}
+
+pub(crate) fn parse_newline<'s, 'i>(
+ state: &'s RefCell<ParseState>,
+) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's {
+ move |i| {
+ newline
+ .span()
+ .map(|span| state.borrow_mut().on_ws(span))
+ .parse(i)
+ }
+}
+
+pub(crate) fn keyval<'s, 'i>(
+ state: &'s RefCell<ParseState>,
+) -> impl FnMut(Input<'i>) -> IResult<Input<'i>, (), ParserError<'i>> + 's {
+ move |i| {
+ parse_keyval
+ .map_res(|(p, kv)| state.borrow_mut().on_keyval(p, kv))
+ .parse(i)
+ }
+}
+
+// keyval = key keyval-sep val
+pub(crate) fn parse_keyval(
+ input: Input<'_>,
+) -> IResult<Input<'_>, (Vec<Key>, TableKeyValue), ParserError<'_>> {
+ (
+ key,
+ cut((
+ one_of(KEYVAL_SEP)
+ .context(Context::Expected(ParserValue::CharLiteral('.')))
+ .context(Context::Expected(ParserValue::CharLiteral('='))),
+ (
+ ws.span(),
+ value(RecursionCheck::default()),
+ line_trailing
+ .context(Context::Expected(ParserValue::CharLiteral('\n')))
+ .context(Context::Expected(ParserValue::CharLiteral('#'))),
+ ),
+ )),
+ )
+ .map_res::<_, _, std::str::Utf8Error>(|(key, (_, v))| {
+ let mut path = key;
+ let key = path.pop().expect("grammar ensures at least 1");
+
+ let (pre, v, suf) = v;
+ let pre = RawString::with_span(pre);
+ let suf = RawString::with_span(suf);
+ let v = v.decorated(pre, suf);
+ Ok((
+ path,
+ TableKeyValue {
+ key,
+ value: Item::Value(v),
+ },
+ ))
+ })
+ .parse(input)
+}