3 use nom8
::combinator
::fail
;
4 use nom8
::combinator
::peek
;
6 use crate::parser
::array
::array
;
7 use crate::parser
::datetime
::date_time
;
8 use crate::parser
::inline_table
::inline_table
;
9 use crate::parser
::numbers
::{float, integer}
;
10 use crate::parser
::prelude
::*;
11 use crate::parser
::strings
::string
;
12 use crate::repr
::{Formatted, Repr}
;
13 use crate::value
as v
;
17 // val = string / boolean / array / inline-table / date-time / float / integer
19 check
: RecursionCheck
,
20 ) -> impl FnMut(Input
<'_
>) -> IResult
<Input
<'_
>, v
::Value
, ParserError
<'_
>> {
23 crate::parser
::strings
::QUOTATION_MARK
|
24 crate::parser
::strings
::APOSTROPHE
=> string
.map(|s
| {
25 v
::Value
::String(Formatted
::new(
29 crate::parser
::array
::ARRAY_OPEN
=> array(check
).map(v
::Value
::Array
),
30 crate::parser
::inline_table
::INLINE_TABLE_OPEN
=> inline_table(check
).map(v
::Value
::InlineTable
),
32 b'
+'
| b'
-'
| b'
0'
..=b'
9'
=> {
33 // Uncommon enough not to be worth optimizing at this time
43 // Report as if they were numbers because its most likely a typo
47 .context(Context
::Expected(ParserValue
::Description("leading digit")))
49 // Report as if they were numbers because its most likely a typo
53 .context(Context
::Expected(ParserValue
::Description("leading digit")))
56 crate::parser
::numbers
::true_
.map(v
::Value
::from
)
57 .context(Context
::Expression("string"))
58 .context(Context
::Expected(ParserValue
::CharLiteral('
"')))
59 .context(Context::Expected(ParserValue::CharLiteral('\'')))
62 crate::parser::numbers::false_.map(v::Value::from)
63 .context(Context::Expression("string
"))
64 .context(Context::Expected(ParserValue::CharLiteral('"'
)))
65 .context(Context
::Expected(ParserValue
::CharLiteral('
\''
)))
68 crate::parser
::numbers
::inf
.map(v
::Value
::from
)
69 .context(Context
::Expression("string"))
70 .context(Context
::Expected(ParserValue
::CharLiteral('
"')))
71 .context(Context::Expected(ParserValue::CharLiteral('\'')))
74 crate::parser::numbers::nan.map(v::Value::from)
75 .context(Context::Expression("string
"))
76 .context(Context::Expected(ParserValue::CharLiteral('"'
)))
77 .context(Context
::Expected(ParserValue
::CharLiteral('
\''
)))
81 .context(Context
::Expression("string"))
82 .context(Context
::Expected(ParserValue
::CharLiteral('
"')))
83 .context(Context::Expected(ParserValue::CharLiteral('\'')))
87 .map_res(|(value, span)| apply_raw(value, span))
92 fn apply_raw(mut val: Value, span: std::ops::Range<usize>) -> Result<Value, std::str::Utf8Error> {
94 Value::String(ref mut f) => {
95 let raw = RawString::with_span(span);
96 f.set_repr_unchecked(Repr::new_unchecked(raw));
98 Value::Integer(ref mut f) => {
99 let raw = RawString::with_span(span);
100 f.set_repr_unchecked(Repr::new_unchecked(raw));
102 Value::Float(ref mut f) => {
103 let raw = RawString::with_span(span);
104 f.set_repr_unchecked(Repr::new_unchecked(raw));
106 Value::Boolean(ref mut f) => {
107 let raw = RawString::with_span(span);
108 f.set_repr_unchecked(Repr::new_unchecked(raw));
110 Value::Datetime(ref mut f) => {
111 let raw = RawString::with_span(span);
112 f.set_repr_unchecked(Repr::new_unchecked(raw));
114 Value::Array(ref mut arr) => {
115 arr.span = Some(span);
117 Value::InlineTable(ref mut table) => {
118 table.span = Some(span);
121 val.decorate("", "");
132 "1979-05-27T00
:32:00.999999",
135 "9_224_617.445_991_228_313",
136 r#"'''I
[dw
]on't need
\d{2} apples'''
"#,
139 trimmed
in raw strings
.
144 r#""\\\"\b/\f\n\r\t\u00E9\U000A0000""#,
145 r#"{ hello = "world", a = 1}
"#,
146 r#"[ { x = 1, a = "2" }
, {a = "a",b = "b", c = "c"}
]"#,
148 for input in inputs {
150 let mut parsed = value(Default::default()).parse(new_input(input)).finish();
151 if let Ok(parsed) = &mut parsed {
152 parsed.despan(input);
154 assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned()));