]> git.proxmox.com Git - rustc.git/blame - vendor/toml_edit/src/parser/value.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / vendor / toml_edit / src / parser / value.rs
CommitLineData
add651ee 1use winnow::combinator::alt;
49aad941
FG
2use winnow::combinator::fail;
3use winnow::combinator::peek;
add651ee 4use winnow::token::any;
0a29b90c
FG
5
6use crate::parser::array::array;
7use crate::parser::datetime::date_time;
8use crate::parser::inline_table::inline_table;
9use crate::parser::numbers::{float, integer};
10use crate::parser::prelude::*;
11use crate::parser::strings::string;
12use crate::repr::{Formatted, Repr};
13use crate::value as v;
14use crate::RawString;
15use crate::Value;
16
17// val = string / boolean / array / inline-table / date-time / float / integer
add651ee
FG
18pub(crate) fn value<'i>(check: RecursionCheck) -> impl Parser<Input<'i>, v::Value, ContextError> {
19 move |input: &mut Input<'i>| {
0a29b90c
FG
20 dispatch!{peek(any);
21 crate::parser::strings::QUOTATION_MARK |
22 crate::parser::strings::APOSTROPHE => string.map(|s| {
23 v::Value::String(Formatted::new(
24 s.into_owned()
25 ))
26 }),
27 crate::parser::array::ARRAY_OPEN => array(check).map(v::Value::Array),
28 crate::parser::inline_table::INLINE_TABLE_OPEN => inline_table(check).map(v::Value::InlineTable),
29 // Date/number starts
30 b'+' | b'-' | b'0'..=b'9' => {
31 // Uncommon enough not to be worth optimizing at this time
32 alt((
33 date_time
34 .map(v::Value::from),
35 float
36 .map(v::Value::from),
37 integer
38 .map(v::Value::from),
39 ))
40 },
41 // Report as if they were numbers because its most likely a typo
42 b'_' => {
43 integer
44 .map(v::Value::from)
add651ee 45 .context(StrContext::Expected(StrContextValue::Description("leading digit")))
0a29b90c
FG
46 },
47 // Report as if they were numbers because its most likely a typo
48 b'.' => {
49 float
50 .map(v::Value::from)
add651ee 51 .context(StrContext::Expected(StrContextValue::Description("leading digit")))
0a29b90c
FG
52 },
53 b't' => {
54 crate::parser::numbers::true_.map(v::Value::from)
add651ee
FG
55 .context(StrContext::Label("string"))
56 .context(StrContext::Expected(StrContextValue::CharLiteral('"')))
57 .context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
0a29b90c
FG
58 },
59 b'f' => {
60 crate::parser::numbers::false_.map(v::Value::from)
add651ee
FG
61 .context(StrContext::Label("string"))
62 .context(StrContext::Expected(StrContextValue::CharLiteral('"')))
63 .context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
0a29b90c
FG
64 },
65 b'i' => {
66 crate::parser::numbers::inf.map(v::Value::from)
add651ee
FG
67 .context(StrContext::Label("string"))
68 .context(StrContext::Expected(StrContextValue::CharLiteral('"')))
69 .context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
0a29b90c
FG
70 },
71 b'n' => {
72 crate::parser::numbers::nan.map(v::Value::from)
add651ee
FG
73 .context(StrContext::Label("string"))
74 .context(StrContext::Expected(StrContextValue::CharLiteral('"')))
75 .context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
0a29b90c
FG
76 },
77 _ => {
78 fail
add651ee
FG
79 .context(StrContext::Label("string"))
80 .context(StrContext::Expected(StrContextValue::CharLiteral('"')))
81 .context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
0a29b90c
FG
82 },
83 }
84 .with_span()
fe692bf9 85 .try_map(|(value, span)| apply_raw(value, span))
49aad941 86 .parse_next(input)
0a29b90c
FG
87 }
88}
89
90fn apply_raw(mut val: Value, span: std::ops::Range<usize>) -> Result<Value, std::str::Utf8Error> {
91 match val {
92 Value::String(ref mut f) => {
93 let raw = RawString::with_span(span);
94 f.set_repr_unchecked(Repr::new_unchecked(raw));
95 }
96 Value::Integer(ref mut f) => {
97 let raw = RawString::with_span(span);
98 f.set_repr_unchecked(Repr::new_unchecked(raw));
99 }
100 Value::Float(ref mut f) => {
101 let raw = RawString::with_span(span);
102 f.set_repr_unchecked(Repr::new_unchecked(raw));
103 }
104 Value::Boolean(ref mut f) => {
105 let raw = RawString::with_span(span);
106 f.set_repr_unchecked(Repr::new_unchecked(raw));
107 }
108 Value::Datetime(ref mut f) => {
109 let raw = RawString::with_span(span);
110 f.set_repr_unchecked(Repr::new_unchecked(raw));
111 }
112 Value::Array(ref mut arr) => {
113 arr.span = Some(span);
114 }
115 Value::InlineTable(ref mut table) => {
116 table.span = Some(span);
117 }
118 };
119 val.decorate("", "");
120 Ok(val)
121}
122
123#[cfg(test)]
124mod test {
125 use super::*;
126
127 #[test]
128 fn values() {
129 let inputs = [
130 "1979-05-27T00:32:00.999999",
131 "-239",
132 "1e200",
133 "9_224_617.445_991_228_313",
134 r#"'''I [dw]on't need \d{2} apples'''"#,
135 r#"'''
136The first newline is
137trimmed in raw strings.
138 All other whitespace
139 is preserved.
140'''"#,
141 r#""Jos\u00E9\n""#,
142 r#""\\\"\b/\f\n\r\t\u00E9\U000A0000""#,
143 r#"{ hello = "world", a = 1}"#,
144 r#"[ { x = 1, a = "2" }, {a = "a",b = "b", c = "c"} ]"#,
145 ];
146 for input in inputs {
147 dbg!(input);
49aad941 148 let mut parsed = value(Default::default()).parse(new_input(input));
0a29b90c
FG
149 if let Ok(parsed) = &mut parsed {
150 parsed.despan(input);
151 }
152 assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned()));
153 }
154 }
155}