1 use crate::parser::array::array;
2 use crate::parser::datetime::date_time;
3 use crate::parser::inline_table::inline_table;
4 use crate::parser::numbers::{boolean, float, integer};
5 use crate::parser::strings::string;
6 use crate::parser::trivia::from_utf8_unchecked;
7 use crate::repr::{Formatted, Repr};
8 use crate::value as v;
9 use crate::Value;
10 use combine::parser::range::recognize_with_value;
11 use combine::stream::RangeStream;
12 use combine::*;
13 
14 // val = string / boolean / array / inline-table / date-time / float / integer
15 parse!(value() -> v::Value, {
16     recognize_with_value(look_ahead(any()).then(|e| {
17         dispatch!(e;
18             crate::parser::strings::QUOTATION_MARK |
19             crate::parser::strings::APOSTROPHE => string().map(|s| {
20                 v::Value::String(Formatted::new(
21                     s,
22                 ))
23             }),
24             crate::parser::array::ARRAY_OPEN => array().map(v::Value::Array),
25             crate::parser::inline_table::INLINE_TABLE_OPEN => inline_table().map(v::Value::InlineTable),
26             // Uncommon enough not to be worth optimizing at this time
27             _ => choice((
28                 boolean()
29                     .map(v::Value::from),
30                 date_time()
31                     .map(v::Value::from),
32                 float()
33                     .map(v::Value::from),
34                 integer()
35                     .map(v::Value::from),
36             )),
37         )
38     })).and_then(|(raw, value)| apply_raw(value, raw))
39 });
40 
apply_raw(mut val: Value, raw: &[u8]) -> Result<Value, std::str::Utf8Error>41 fn apply_raw(mut val: Value, raw: &[u8]) -> Result<Value, std::str::Utf8Error> {
42     match val {
43         Value::String(ref mut f) => {
44             let raw = std::str::from_utf8(raw)?;
45             f.set_repr_unchecked(Repr::new_unchecked(raw));
46         }
47         Value::Integer(ref mut f) => {
48             let raw = unsafe { from_utf8_unchecked(raw, "`integer()` filters out non-ASCII") };
49             f.set_repr_unchecked(Repr::new_unchecked(raw));
50         }
51         Value::Float(ref mut f) => {
52             let raw = unsafe { from_utf8_unchecked(raw, "`float()` filters out non-ASCII") };
53             f.set_repr_unchecked(Repr::new_unchecked(raw));
54         }
55         Value::Boolean(ref mut f) => {
56             let raw = unsafe { from_utf8_unchecked(raw, "`boolean()` filters out non-ASCII") };
57             f.set_repr_unchecked(Repr::new_unchecked(raw));
58         }
59         Value::Datetime(ref mut f) => {
60             let raw = unsafe { from_utf8_unchecked(raw, "`date_time()` filters out non-ASCII") };
61             f.set_repr_unchecked(Repr::new_unchecked(raw));
62         }
63         Value::Array(_) | Value::InlineTable(_) => {}
64     };
65     val.decorate("", "");
66     Ok(val)
67 }
68