1 | use std::cell::RefCell; |
2 | |
3 | use winnow::combinator::cut_err; |
4 | use winnow::combinator::eof; |
5 | use winnow::combinator::opt; |
6 | use winnow::combinator::peek; |
7 | use winnow::combinator::repeat; |
8 | use winnow::combinator::trace; |
9 | use winnow::token::any; |
10 | use winnow::token::one_of; |
11 | |
12 | use crate::key::Key; |
13 | use crate::parser::inline_table::KEYVAL_SEP; |
14 | use crate::parser::key::key; |
15 | use crate::parser::prelude::*; |
16 | use crate::parser::state::ParseState; |
17 | use crate::parser::table::table; |
18 | use crate::parser::trivia::{comment, line_ending, line_trailing, newline, ws}; |
19 | use crate::parser::value::value; |
20 | use crate::Item; |
21 | use crate::RawString; |
22 | |
23 | // ;; TOML |
24 | |
25 | // toml = expression *( newline expression ) |
26 | |
27 | // expression = ( ( ws comment ) / |
28 | // ( ws keyval ws [ comment ] ) / |
29 | // ( ws table ws [ comment ] ) / |
30 | // ws ) |
31 | pub(crate) fn document<'s, 'i>( |
32 | state_ref: &'s RefCell<ParseState>, |
33 | ) -> impl ModalParser<Input<'i>, (), ContextError> + 's { |
34 | move |i: &mut Input<'i>| { |
35 | ( |
36 | // Remove BOM if present |
37 | opt(b" \xEF\xBB\xBF" ), |
38 | parse_ws(state_ref), |
39 | repeat(0.., ( |
40 | dispatch! {peek(any); |
41 | crate::parser::trivia::COMMENT_START_SYMBOL => cut_err(parse_comment(state_ref)), |
42 | crate::parser::table::STD_TABLE_OPEN => cut_err(table(state_ref)), |
43 | crate::parser::trivia::LF | |
44 | crate::parser::trivia::CR => parse_newline(state_ref), |
45 | _ => cut_err(keyval(state_ref)), |
46 | }, |
47 | parse_ws(state_ref), |
48 | )) |
49 | .map(|()| ()), |
50 | eof, |
51 | ).void().parse_next(input:i) |
52 | } |
53 | } |
54 | |
55 | pub(crate) fn parse_comment<'s, 'i>( |
56 | state: &'s RefCell<ParseState>, |
57 | ) -> impl ModalParser<Input<'i>, (), ContextError> + 's { |
58 | move |i: &mut Input<'i>| { |
59 | (comment, line_ending) |
60 | .span() |
61 | .map(|span| { |
62 | state.borrow_mut().on_comment(span); |
63 | }) |
64 | .parse_next(input:i) |
65 | } |
66 | } |
67 | |
68 | pub(crate) fn parse_ws<'s, 'i>( |
69 | state: &'s RefCell<ParseState>, |
70 | ) -> impl ModalParser<Input<'i>, (), ContextError> + 's { |
71 | move |i: &mut Input<'i>| { |
72 | ws.span() |
73 | .map(|span| state.borrow_mut().on_ws(span)) |
74 | .parse_next(input:i) |
75 | } |
76 | } |
77 | |
78 | pub(crate) fn parse_newline<'s, 'i>( |
79 | state: &'s RefCell<ParseState>, |
80 | ) -> impl ModalParser<Input<'i>, (), ContextError> + 's { |
81 | move |i: &mut Input<'i>| { |
82 | newline |
83 | .span() |
84 | .map(|span| state.borrow_mut().on_ws(span)) |
85 | .parse_next(input:i) |
86 | } |
87 | } |
88 | |
89 | pub(crate) fn keyval<'s, 'i>( |
90 | state: &'s RefCell<ParseState>, |
91 | ) -> impl ModalParser<Input<'i>, (), ContextError> + 's { |
92 | move |i: &mut Input<'i>| { |
93 | parse_keyval |
94 | .try_map(|(p, kv)| state.borrow_mut().on_keyval(p, kv)) |
95 | .parse_next(input:i) |
96 | } |
97 | } |
98 | |
99 | // keyval = key keyval-sep val |
100 | pub(crate) fn parse_keyval(input: &mut Input<'_>) -> ModalResult<(Vec<Key>, (Key, Item))> { |
101 | trace( |
102 | "keyval" , |
103 | ( |
104 | key, |
105 | cut_err(( |
106 | one_of(KEYVAL_SEP) |
107 | .context(StrContext::Expected(StrContextValue::CharLiteral('.' ))) |
108 | .context(StrContext::Expected(StrContextValue::CharLiteral('=' ))), |
109 | ( |
110 | ws.span(), |
111 | value, |
112 | line_trailing |
113 | .context(StrContext::Expected(StrContextValue::CharLiteral(' \n' ))) |
114 | .context(StrContext::Expected(StrContextValue::CharLiteral('#' ))), |
115 | ), |
116 | )), |
117 | ) |
118 | .try_map::<_, _, std::str::Utf8Error>(|(key, (_, v))| { |
119 | let mut path = key; |
120 | let key = path.pop().expect("grammar ensures at least 1" ); |
121 | |
122 | let (pre, v, suf) = v; |
123 | let pre = RawString::with_span(pre); |
124 | let suf = RawString::with_span(suf); |
125 | let v = v.decorated(pre, suf); |
126 | Ok((path, (key, Item::Value(v)))) |
127 | }), |
128 | ) |
129 | .parse_next(input) |
130 | } |
131 | |