diff options
Diffstat (limited to 'vendor/toml_edit/src')
-rw-r--r-- | vendor/toml_edit/src/array.rs | 50 | ||||
-rw-r--r-- | vendor/toml_edit/src/de/key.rs | 13 | ||||
-rw-r--r-- | vendor/toml_edit/src/de/table_enum.rs | 76 | ||||
-rw-r--r-- | vendor/toml_edit/src/de/value.rs | 2 | ||||
-rw-r--r-- | vendor/toml_edit/src/encode.rs | 40 | ||||
-rw-r--r-- | vendor/toml_edit/src/inline_table.rs | 34 | ||||
-rw-r--r-- | vendor/toml_edit/src/item.rs | 9 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/datetime.rs | 36 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/errors.rs | 3 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/inline_table.rs | 23 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/key.rs | 2 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/mod.rs | 4 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/numbers.rs | 9 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/state.rs | 8 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/strings.rs | 8 | ||||
-rw-r--r-- | vendor/toml_edit/src/parser/value.rs | 2 | ||||
-rw-r--r-- | vendor/toml_edit/src/ser/map.rs | 271 | ||||
-rw-r--r-- | vendor/toml_edit/src/ser/mod.rs | 2 | ||||
-rw-r--r-- | vendor/toml_edit/src/ser/value.rs | 28 | ||||
-rw-r--r-- | vendor/toml_edit/src/table.rs | 6 | ||||
-rw-r--r-- | vendor/toml_edit/src/value.rs | 1 |
21 files changed, 525 insertions, 102 deletions
diff --git a/vendor/toml_edit/src/array.rs b/vendor/toml_edit/src/array.rs index 045b451e0..97033de58 100644 --- a/vendor/toml_edit/src/array.rs +++ b/vendor/toml_edit/src/array.rs @@ -317,6 +317,56 @@ impl Array { .retain(|item| item.as_value().map(&mut keep).unwrap_or(false)); } + /// Sorts the slice with a comparator function. + /// + /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case. + /// + /// The comparator function must define a total ordering for the elements in the slice. If + /// the ordering is not total, the order of the elements is unspecified. An order is a + /// total order if it is (for all `a`, `b` and `c`): + /// + /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and + /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. + /// + /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use + /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. + #[inline] + pub fn sort_by<F>(&mut self, mut compare: F) + where + F: FnMut(&Value, &Value) -> std::cmp::Ordering, + { + self.values.sort_by(move |lhs, rhs| { + let lhs = lhs.as_value(); + let rhs = rhs.as_value(); + match (lhs, rhs) { + (None, None) => std::cmp::Ordering::Equal, + (Some(_), None) => std::cmp::Ordering::Greater, + (None, Some(_)) => std::cmp::Ordering::Less, + (Some(lhs), Some(rhs)) => compare(lhs, rhs), + } + }) + } + + /// Sorts the array with a key extraction function. + /// + /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*)) + /// worst-case, where the key function is *O*(*m*). + #[inline] + pub fn sort_by_key<K, F>(&mut self, mut f: F) + where + F: FnMut(&Value) -> K, + K: Ord, + { + #[allow(clippy::manual_map)] // needed for lifetimes + self.values.sort_by_key(move |item| { + if let Some(value) = item.as_value() { + Some(f(value)) + } else { + None + } + }); + } + fn value_op<T>( &mut self, v: Value, diff --git a/vendor/toml_edit/src/de/key.rs b/vendor/toml_edit/src/de/key.rs index 3da41df41..a3b282566 100644 --- a/vendor/toml_edit/src/de/key.rs +++ b/vendor/toml_edit/src/de/key.rs @@ -62,9 +62,20 @@ impl<'de> serde::de::Deserializer<'de> for KeyDeserializer { self.deserialize_any(visitor) } + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + serde::forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq - bytes byte_buf map option unit newtype_struct + bytes byte_buf map option unit ignored_any unit_struct tuple_struct tuple identifier } } diff --git a/vendor/toml_edit/src/de/table_enum.rs b/vendor/toml_edit/src/de/table_enum.rs index 197ad6ea7..0ceeab62f 100644 --- a/vendor/toml_edit/src/de/table_enum.rs +++ b/vendor/toml_edit/src/de/table_enum.rs @@ -16,6 +16,20 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { fn unit_variant(self) -> Result<(), Self::Error> { match self.value { + crate::Item::ArrayOfTables(values) => { + if values.is_empty() { + Ok(()) + } else { + Err(Error::custom("expected empty array", values.span())) + } + } + crate::Item::Value(crate::Value::Array(values)) => { + if values.is_empty() { + Ok(()) + } else { + Err(Error::custom("expected empty table", values.span())) + } + } crate::Item::Table(values) => { if values.is_empty() { Ok(()) @@ -49,9 +63,41 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { V: serde::de::Visitor<'de>, { match self.value { + crate::Item::ArrayOfTables(values) => { + let values_span = values.span(); + let tuple_values = values.values.into_iter().collect::<Vec<_>>(); + + if tuple_values.len() == len { + serde::de::Deserializer::deserialize_seq( + super::ArrayDeserializer::new(tuple_values, values_span), + visitor, + ) + } else { + Err(Error::custom( + format!("expected tuple with length {}", len), + values_span, + )) + } + } + crate::Item::Value(crate::Value::Array(values)) => { + let values_span = values.span(); + let tuple_values = values.values.into_iter().collect::<Vec<_>>(); + + if tuple_values.len() == len { + serde::de::Deserializer::deserialize_seq( + super::ArrayDeserializer::new(tuple_values, values_span), + visitor, + ) + } else { + Err(Error::custom( + format!("expected tuple with length {}", len), + values_span, + )) + } + } crate::Item::Table(values) => { let values_span = values.span(); - let tuple_values = values + let tuple_values: Result<Vec<_>, _> = values .items .into_iter() .enumerate() @@ -68,17 +114,8 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { )), }, ) - // Fold all values into a `Vec`, or return the first error. - .fold(Ok(Vec::with_capacity(len)), |result, value_result| { - result.and_then(move |mut tuple_values| match value_result { - Ok(value) => { - tuple_values.push(value); - Ok(tuple_values) - } - // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>` - Err(e) => Err(e), - }) - })?; + .collect(); + let tuple_values = tuple_values?; if tuple_values.len() == len { serde::de::Deserializer::deserialize_seq( @@ -94,7 +131,7 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { } crate::Item::Value(crate::Value::InlineTable(values)) => { let values_span = values.span(); - let tuple_values = values + let tuple_values: Result<Vec<_>, _> = values .items .into_iter() .enumerate() @@ -111,17 +148,8 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { )), }, ) - // Fold all values into a `Vec`, or return the first error. - .fold(Ok(Vec::with_capacity(len)), |result, value_result| { - result.and_then(move |mut tuple_values| match value_result { - Ok(value) => { - tuple_values.push(value); - Ok(tuple_values) - } - // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>` - Err(e) => Err(e), - }) - })?; + .collect(); + let tuple_values = tuple_values?; if tuple_values.len() == len { serde::de::Deserializer::deserialize_seq( diff --git a/vendor/toml_edit/src/de/value.rs b/vendor/toml_edit/src/de/value.rs index 39842875a..d3cf87fc6 100644 --- a/vendor/toml_edit/src/de/value.rs +++ b/vendor/toml_edit/src/de/value.rs @@ -5,7 +5,7 @@ use crate::de::Error; /// Deserialization implementation for TOML [values][crate::Value]. /// -/// Can be creater either directly from TOML strings, using [`std::str::FromStr`], +/// Can be created either directly from TOML strings, using [`std::str::FromStr`], /// or from parsed [values][crate::Value] using [`serde::de::IntoDeserializer::into_deserializer`]. /// /// # Example diff --git a/vendor/toml_edit/src/encode.rs b/vendor/toml_edit/src/encode.rs index 9940f282b..db10e29ea 100644 --- a/vendor/toml_edit/src/encode.rs +++ b/vendor/toml_edit/src/encode.rs @@ -390,7 +390,7 @@ pub(crate) fn to_string_repr( '\u{8}' => output.push_str("\\b"), '\u{9}' => output.push_str("\\t"), '\u{a}' => match style { - StringStyle::NewlineTripple => output.push('\n'), + StringStyle::NewlineTriple => output.push('\n'), StringStyle::OnelineSingle => output.push_str("\\n"), _ => unreachable!(), }, @@ -412,59 +412,56 @@ pub(crate) fn to_string_repr( #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub(crate) enum StringStyle { - NewlineTripple, - OnelineTripple, + NewlineTriple, + OnelineTriple, OnelineSingle, } impl StringStyle { fn literal_start(self) -> &'static str { match self { - Self::NewlineTripple => "'''\n", - Self::OnelineTripple => "'''", + Self::NewlineTriple => "'''\n", + Self::OnelineTriple => "'''", Self::OnelineSingle => "'", } } fn literal_end(self) -> &'static str { match self { - Self::NewlineTripple => "'''", - Self::OnelineTripple => "'''", + Self::NewlineTriple => "'''", + Self::OnelineTriple => "'''", Self::OnelineSingle => "'", } } fn standard_start(self) -> &'static str { match self { - Self::NewlineTripple => "\"\"\"\n", - // note: OnelineTripple can happen if do_pretty wants to do + Self::NewlineTriple => "\"\"\"\n", + // note: OnelineTriple can happen if do_pretty wants to do // '''it's one line''' // but literal == false - Self::OnelineTripple | Self::OnelineSingle => "\"", + Self::OnelineTriple | Self::OnelineSingle => "\"", } } fn standard_end(self) -> &'static str { match self { - Self::NewlineTripple => "\"\"\"", - // note: OnelineTripple can happen if do_pretty wants to do + Self::NewlineTriple => "\"\"\"", + // note: OnelineTriple can happen if do_pretty wants to do // '''it's one line''' // but literal == false - Self::OnelineTripple | Self::OnelineSingle => "\"", + Self::OnelineTriple | Self::OnelineSingle => "\"", } } } fn infer_style(value: &str) -> (StringStyle, bool) { - // For doing pretty prints we store in a new String - // because there are too many cases where pretty cannot - // work. We need to determine: + // We need to determine: // - if we are a "multi-line" pretty (if there are \n) // - if ['''] appears if multi or ['] if single // - if there are any invalid control characters // // Doing it any other way would require multiple passes // to determine if a pretty string works or not. - let mut out = String::with_capacity(value.len() * 2); let mut ty = StringStyle::OnelineSingle; // found consecutive single quotes let mut max_found_singles = 0; @@ -490,18 +487,17 @@ fn infer_style(value: &str) -> (StringStyle, bool) { '\\' => { prefer_literal = true; } - '\n' => ty = StringStyle::NewlineTripple, + '\n' => ty = StringStyle::NewlineTriple, // Escape codes are needed if any ascii control // characters are present, including \b \f \r. c if c <= '\u{1f}' || c == '\u{7f}' => can_be_pretty = false, _ => {} } - out.push(ch); } else { // the string cannot be represented as pretty, // still check if it should be multiline if ch == '\n' { - ty = StringStyle::NewlineTripple; + ty = StringStyle::NewlineTriple; } } } @@ -513,7 +509,7 @@ fn infer_style(value: &str) -> (StringStyle, bool) { can_be_pretty = false; } if !can_be_pretty { - debug_assert!(ty != StringStyle::OnelineTripple); + debug_assert!(ty != StringStyle::OnelineTriple); return (ty, false); } if found_singles > max_found_singles { @@ -522,7 +518,7 @@ fn infer_style(value: &str) -> (StringStyle, bool) { debug_assert!(max_found_singles < 3); if ty == StringStyle::OnelineSingle && max_found_singles >= 1 { // no newlines, but must use ''' because it has ' in it - ty = StringStyle::OnelineTripple; + ty = StringStyle::OnelineTriple; } (ty, true) } diff --git a/vendor/toml_edit/src/inline_table.rs b/vendor/toml_edit/src/inline_table.rs index 3dc6c0c05..cbd64adb3 100644 --- a/vendor/toml_edit/src/inline_table.rs +++ b/vendor/toml_edit/src/inline_table.rs @@ -11,6 +11,8 @@ use crate::{InternalString, Item, KeyMut, RawString, Table, Value}; pub struct InlineTable { // `preamble` represents whitespaces in an empty table preamble: RawString, + // Whether to hide an empty table + pub(crate) implicit: bool, // prefix before `{` and suffix after `}` decor: Decor, pub(crate) span: Option<std::ops::Range<usize>>, @@ -55,10 +57,10 @@ impl InlineTable { values } - pub(crate) fn append_values<'s, 'c>( + pub(crate) fn append_values<'s>( &'s self, parent: &[&'s Key], - values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>, + values: &mut Vec<(Vec<&'s Key>, &'s Value)>, ) { for value in self.items.values() { let mut path = parent.to_vec(); @@ -133,6 +135,32 @@ impl InlineTable { } } + /// If a table has no key/value pairs and implicit, it will not be displayed. + /// + /// # Examples + /// + /// ```notrust + /// [target."x86_64/windows.json".dependencies] + /// ``` + /// + /// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit. + /// + /// ``` + /// use toml_edit::Document; + /// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml"); + /// + /// doc["a"].as_table_mut().unwrap().set_implicit(true); + /// assert_eq!(doc.to_string(), "[a.b]\n"); + /// ``` + pub(crate) fn set_implicit(&mut self, implicit: bool) { + self.implicit = implicit; + } + + /// If a table has no key/value pairs and implicit, it will not be displayed. + pub(crate) fn is_implicit(&self) -> bool { + self.implicit + } + /// Change this table's dotted status pub fn set_dotted(&mut self, yes: bool) { self.dotted = yes; @@ -439,7 +467,7 @@ fn decorate_inline_table(table: &mut InlineTable) { for (key_decor, value) in table .items .iter_mut() - .filter(|&(_, ref kv)| kv.value.is_value()) + .filter(|(_, kv)| kv.value.is_value()) .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap())) { key_decor.clear(); diff --git a/vendor/toml_edit/src/item.rs b/vendor/toml_edit/src/item.rs index 2025fd916..a14056319 100644 --- a/vendor/toml_edit/src/item.rs +++ b/vendor/toml_edit/src/item.rs @@ -7,9 +7,10 @@ use crate::table::TableLike; use crate::{Array, InlineTable, Table, Value}; /// Type representing either a value, a table, an array of tables, or none. -#[derive(Debug)] +#[derive(Debug, Default)] pub enum Item { /// Type representing none. + #[default] None, /// Type representing value. Value(Value), @@ -328,12 +329,6 @@ impl Clone for Item { } } -impl Default for Item { - fn default() -> Self { - Item::None - } -} - impl FromStr for Item { type Err = crate::TomlError; diff --git a/vendor/toml_edit/src/parser/datetime.rs b/vendor/toml_edit/src/parser/datetime.rs index 6e89b9779..96a3854d4 100644 --- a/vendor/toml_edit/src/parser/datetime.rs +++ b/vendor/toml_edit/src/parser/datetime.rs @@ -9,6 +9,7 @@ use winnow::combinator::alt; use winnow::combinator::cut_err; use winnow::combinator::opt; use winnow::combinator::preceded; +use winnow::stream::Stream as _; use winnow::token::one_of; use winnow::token::take_while; use winnow::trace::trace; @@ -53,12 +54,35 @@ pub(crate) fn date_time(input: &mut Input<'_>) -> PResult<Datetime> { // full-date = date-fullyear "-" date-month "-" date-mday pub(crate) fn full_date(input: &mut Input<'_>) -> PResult<Date> { - trace( - "full-date", - (date_fullyear, b'-', cut_err((date_month, b'-', date_mday))) - .map(|(year, _, (month, _, day))| Date { year, month, day }), - ) - .parse_next(input) + trace("full-date", full_date_).parse_next(input) +} + +fn full_date_(input: &mut Input<'_>) -> PResult<Date> { + let year = date_fullyear.parse_next(input)?; + let _ = b'-'.parse_next(input)?; + let month = cut_err(date_month).parse_next(input)?; + let _ = cut_err(b'-').parse_next(input)?; + let day_start = input.checkpoint(); + let day = cut_err(date_mday).parse_next(input)?; + + let is_leap_year = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); + let max_days_in_month = match month { + 2 if is_leap_year => 29, + 2 => 28, + 4 | 6 | 9 | 11 => 30, + _ => 31, + }; + if max_days_in_month < day { + input.reset(day_start); + return Err(winnow::error::ErrMode::from_external_error( + input, + winnow::error::ErrorKind::Verify, + CustomError::OutOfRange, + ) + .cut()); + } + + Ok(Date { year, month, day }) } // partial-time = time-hour ":" time-minute ":" time-second [time-secfrac] diff --git a/vendor/toml_edit/src/parser/errors.rs b/vendor/toml_edit/src/parser/errors.rs index 859ed5334..685e9f716 100644 --- a/vendor/toml_edit/src/parser/errors.rs +++ b/vendor/toml_edit/src/parser/errors.rs @@ -166,7 +166,6 @@ fn translate_position(input: &[u8], index: usize) -> (usize, usize) { None => 0, }; let line = input[0..line_start].iter().filter(|b| **b == b'\n').count(); - let line = line; let column = std::str::from_utf8(&input[line_start..=index]) .map(|s| s.chars().count() - 1) @@ -310,7 +309,7 @@ impl Display for CustomError { ) } CustomError::OutOfRange => write!(f, "value is out of range"), - CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceded"), + CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded"), } } } diff --git a/vendor/toml_edit/src/parser/inline_table.rs b/vendor/toml_edit/src/parser/inline_table.rs index 994e00336..f7cf2e9c5 100644 --- a/vendor/toml_edit/src/parser/inline_table.rs +++ b/vendor/toml_edit/src/parser/inline_table.rs @@ -44,6 +44,16 @@ fn table_from_pairs( for (path, kv) in v { let table = descend_path(&mut root, &path)?; + + // "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed" + let mixed_table_types = table.is_dotted() == path.is_empty(); + if mixed_table_types { + return Err(CustomError::DuplicateKey { + key: kv.key.get().into(), + table: None, + }); + } + let key: InternalString = kv.key.get_internal().into(); match table.items.entry(key) { Entry::Vacant(o) => { @@ -64,15 +74,26 @@ fn descend_path<'a>( mut table: &'a mut InlineTable, path: &'a [Key], ) -> Result<&'a mut InlineTable, CustomError> { + let dotted = !path.is_empty(); for (i, key) in path.iter().enumerate() { let entry = table.entry_format(key).or_insert_with(|| { let mut new_table = InlineTable::new(); - new_table.set_dotted(true); + new_table.set_implicit(dotted); + new_table.set_dotted(dotted); Value::InlineTable(new_table) }); match *entry { Value::InlineTable(ref mut sweet_child_of_mine) => { + // Since tables cannot be defined more than once, redefining such tables using a + // [table] header is not allowed. Likewise, using dotted keys to redefine tables + // already defined in [table] form is not allowed. + if dotted && !sweet_child_of_mine.is_implicit() { + return Err(CustomError::DuplicateKey { + key: key.get().into(), + table: None, + }); + } table = sweet_child_of_mine; } ref v => { diff --git a/vendor/toml_edit/src/parser/key.rs b/vendor/toml_edit/src/parser/key.rs index 12715da19..bd8804a23 100644 --- a/vendor/toml_edit/src/parser/key.rs +++ b/vendor/toml_edit/src/parser/key.rs @@ -96,7 +96,7 @@ mod test { let cases = [ ("a", "a"), (r#""hello\n ""#, "hello\n "), - (r#"'hello\n '"#, "hello\\n "), + (r"'hello\n '", "hello\\n "), ]; for (input, expected) in cases { diff --git a/vendor/toml_edit/src/parser/mod.rs b/vendor/toml_edit/src/parser/mod.rs index 1b3cc4f0c..eb4755055 100644 --- a/vendor/toml_edit/src/parser/mod.rs +++ b/vendor/toml_edit/src/parser/mod.rs @@ -182,10 +182,10 @@ hosts = [ "omega" ] - 'some.wierd .stuff' = """ + 'some.weird .stuff' = """ like that - # """ # this broke my sintax highlighting + # """ # this broke my syntax highlighting " also. like " = ''' that ''' diff --git a/vendor/toml_edit/src/parser/numbers.rs b/vendor/toml_edit/src/parser/numbers.rs index 6e4757f06..4c77f51c1 100644 --- a/vendor/toml_edit/src/parser/numbers.rs +++ b/vendor/toml_edit/src/parser/numbers.rs @@ -301,7 +301,7 @@ pub(crate) fn inf(input: &mut Input<'_>) -> PResult<f64> { const INF: &[u8] = b"inf"; // nan = %x6e.61.6e ; nan pub(crate) fn nan(input: &mut Input<'_>) -> PResult<f64> { - tag(NAN).value(f64::NAN).parse_next(input) + tag(NAN).value(f64::NAN.copysign(1.0)).parse_next(input) } const NAN: &[u8] = b"nan"; @@ -353,6 +353,7 @@ mod test { fn assert_float_eq(actual: f64, expected: f64) { if expected.is_nan() { assert!(actual.is_nan()); + assert_eq!(expected.is_sign_positive(), actual.is_sign_positive()); } else if expected.is_infinite() { assert!(actual.is_infinite()); assert_eq!(expected.is_sign_positive(), actual.is_sign_positive()); @@ -376,9 +377,9 @@ mod test { ("9_224_617.445_991_228_313", 9_224_617.445_991_227), ("-1.7976931348623157e+308", std::f64::MIN), ("1.7976931348623157e+308", std::f64::MAX), - ("nan", f64::NAN), - ("+nan", f64::NAN), - ("-nan", f64::NAN), + ("nan", f64::NAN.copysign(1.0)), + ("+nan", f64::NAN.copysign(1.0)), + ("-nan", f64::NAN.copysign(-1.0)), ("inf", f64::INFINITY), ("+inf", f64::INFINITY), ("-inf", f64::NEG_INFINITY), diff --git a/vendor/toml_edit/src/parser/state.rs b/vendor/toml_edit/src/parser/state.rs index efa884d2f..235391c75 100644 --- a/vendor/toml_edit/src/parser/state.rs +++ b/vendor/toml_edit/src/parser/state.rs @@ -94,7 +94,7 @@ impl ParseState { Ok(()) } - pub(crate) fn start_aray_table( + pub(crate) fn start_array_table( &mut self, path: Vec<Key>, decor: Decor, @@ -217,9 +217,9 @@ impl ParseState { Ok(()) } - pub(crate) fn descend_path<'t, 'k>( + pub(crate) fn descend_path<'t>( mut table: &'t mut Table, - path: &'k [Key], + path: &[Key], dotted: bool, ) -> Result<&'t mut Table, CustomError> { for (i, key) in path.iter().enumerate() { @@ -297,7 +297,7 @@ impl ParseState { .take() .map(RawString::with_span) .unwrap_or_default(); - self.start_aray_table( + self.start_array_table( path, Decor::new(leading, RawString::with_span(trailing)), span, diff --git a/vendor/toml_edit/src/parser/strings.rs b/vendor/toml_edit/src/parser/strings.rs index 26f9cc248..8c366fad5 100644 --- a/vendor/toml_edit/src/parser/strings.rs +++ b/vendor/toml_edit/src/parser/strings.rs @@ -440,10 +440,10 @@ The quick brown \ #[test] fn literal_string() { let inputs = [ - r#"'C:\Users\nodejs\templates'"#, - r#"'\\ServerX\admin$\system32\'"#, + r"'C:\Users\nodejs\templates'", + r"'\\ServerX\admin$\system32\'", r#"'Tom "Dubs" Preston-Werner'"#, - r#"'<\i\c*\s*>'"#, + r"'<\i\c*\s*>'", ]; for input in &inputs { @@ -456,7 +456,7 @@ The quick brown \ #[test] fn ml_literal_string() { let inputs = [ - r#"'''I [dw]on't need \d{2} apples'''"#, + r"'''I [dw]on't need \d{2} apples'''", r#"''''one_quote''''"#, ]; for input in &inputs { diff --git a/vendor/toml_edit/src/parser/value.rs b/vendor/toml_edit/src/parser/value.rs index 14cd951c4..9e1f0781c 100644 --- a/vendor/toml_edit/src/parser/value.rs +++ b/vendor/toml_edit/src/parser/value.rs @@ -131,7 +131,7 @@ mod test { "-239", "1e200", "9_224_617.445_991_228_313", - r#"'''I [dw]on't need \d{2} apples'''"#, + r"'''I [dw]on't need \d{2} apples'''", r#"''' The first newline is trimmed in raw strings. diff --git a/vendor/toml_edit/src/ser/map.rs b/vendor/toml_edit/src/ser/map.rs index d743e3d5d..47e56ba48 100644 --- a/vendor/toml_edit/src/ser/map.rs +++ b/vendor/toml_edit/src/ser/map.rs @@ -1,4 +1,4 @@ -use super::{Error, KeySerializer}; +use super::{Error, KeySerializer, SerializeValueArray, ValueSerializer}; #[doc(hidden)] pub enum SerializeMap { @@ -165,7 +165,6 @@ impl serde::ser::SerializeMap for SerializeInlineTable { where T: serde::ser::Serialize, { - self.key = None; self.key = Some(input.serialize(KeySerializer)?); Ok(()) } @@ -174,7 +173,8 @@ impl serde::ser::SerializeMap for SerializeInlineTable { where T: serde::ser::Serialize, { - let res = value.serialize(super::ValueSerializer {}); + let mut value_serializer = MapValueSerializer::new(); + let res = value.serialize(&mut value_serializer); match res { Ok(item) => { let key = self.key.take().unwrap(); @@ -185,7 +185,7 @@ impl serde::ser::SerializeMap for SerializeInlineTable { self.items.insert(key, kv); } Err(e) => { - if e != Error::UnsupportedNone { + if !(e == Error::UnsupportedNone && value_serializer.is_none) { return Err(e); } } @@ -210,7 +210,8 @@ impl serde::ser::SerializeStruct for SerializeInlineTable { where T: serde::ser::Serialize, { - let res = value.serialize(super::ValueSerializer {}); + let mut value_serializer = MapValueSerializer::new(); + let res = value.serialize(&mut value_serializer); match res { Ok(item) => { let kv = crate::table::TableKeyValue::new( @@ -220,7 +221,7 @@ impl serde::ser::SerializeStruct for SerializeInlineTable { self.items.insert(crate::InternalString::from(key), kv); } Err(e) => { - if e != Error::UnsupportedNone { + if !(e == Error::UnsupportedNone && value_serializer.is_none) { return Err(e); } } @@ -403,3 +404,261 @@ impl serde::ser::Serializer for DatetimeFieldSerializer { Err(Error::DateInvalid) } } + +#[derive(Default)] +struct MapValueSerializer { + is_none: bool, +} + +impl MapValueSerializer { + fn new() -> Self { + Self { is_none: false } + } +} + +impl serde::ser::Serializer for &mut MapValueSerializer { + type Ok = crate::Value; + type Error = Error; + type SerializeSeq = super::SerializeValueArray; + type SerializeTuple = super::SerializeValueArray; + type SerializeTupleStruct = super::SerializeValueArray; + type SerializeTupleVariant = super::SerializeTupleVariant; + type SerializeMap = super::SerializeMap; + type SerializeStruct = super::SerializeMap; + type SerializeStructVariant = super::SerializeStructVariant; + + fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_bool(v) + } + + fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_i8(v) + } + + fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_i16(v) + } + + fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_i32(v) + } + + fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_i64(v) + } + + fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_u8(v) + } + + fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_u16(v) + } + + fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_u32(v) + } + + fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_u64(v) + } + + fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_f32(v) + } + + fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_f64(v) + } + + fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_char(v) + } + + fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_str(v) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_bytes(value) + } + + fn serialize_none(self) -> Result<Self::Ok, Self::Error> { + self.is_none = true; + Err(Error::UnsupportedNone) + } + + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + ValueSerializer::new().serialize_some(value) + } + + fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_unit() + } + + fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_unit_struct(name) + } + + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result<Self::Ok, Self::Error> { + ValueSerializer::new().serialize_unit_variant(name, variant_index, variant) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + name: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + ValueSerializer::new().serialize_newtype_struct(name, value) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<Self::Ok, Self::Error> + where + T: serde::ser::Serialize, + { + ValueSerializer::new().serialize_newtype_variant(name, variant_index, variant, value) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { + ValueSerializer::new().serialize_seq(len) + } + + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { + ValueSerializer::new().serialize_tuple(len) + } + + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct, Self::Error> { + ValueSerializer::new().serialize_tuple_struct(name, len) + } + + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, Self::Error> { + ValueSerializer::new().serialize_tuple_variant(name, variant_index, variant, len) + } + + fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { + ValueSerializer::new().serialize_map(len) + } + + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, Self::Error> { + ValueSerializer::new().serialize_struct(name, len) + } + + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result<Self::SerializeStructVariant, Self::Error> { + ValueSerializer::new().serialize_struct_variant(name, variant_index, variant, len) + } +} + +pub type SerializeTupleVariant = SerializeVariant<SerializeValueArray>; +pub type SerializeStructVariant = SerializeVariant<SerializeMap>; + +pub struct SerializeVariant<T> { + variant: &'static str, + inner: T, +} + +impl SerializeVariant<SerializeValueArray> { + pub(crate) fn tuple(variant: &'static str, len: usize) -> Self { + Self { + variant, + inner: SerializeValueArray::with_capacity(len), + } + } +} + +impl SerializeVariant<SerializeMap> { + pub(crate) fn struct_(variant: &'static str, len: usize) -> Self { + Self { + variant, + inner: SerializeMap::table_with_capacity(len), + } + } +} + +impl serde::ser::SerializeTupleVariant for SerializeVariant<SerializeValueArray> { + type Ok = crate::Value; + type Error = Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error> + where + T: serde::ser::Serialize, + { + serde::ser::SerializeSeq::serialize_element(&mut self.inner, value) + } + + fn end(self) -> Result<Self::Ok, Self::Error> { + let inner = serde::ser::SerializeSeq::end(self.inner)?; + let mut items = crate::table::KeyValuePairs::new(); + let kv = crate::table::TableKeyValue::new( + crate::Key::new(self.variant), + crate::Item::Value(inner), + ); + items.insert(crate::InternalString::from(self.variant), kv); + Ok(crate::Value::InlineTable(crate::InlineTable::with_pairs( + items, + ))) + } +} + +impl serde::ser::SerializeStructVariant for SerializeVariant<SerializeMap> { + type Ok = crate::Value; + type Error = Error; + + #[inline] + fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: serde::ser::Serialize + ?Sized, + { + serde::ser::SerializeStruct::serialize_field(&mut self.inner, key, value) + } + + #[inline] + fn end(self) -> Result<Self::Ok, Self::Error> { + let inner = serde::ser::SerializeStruct::end(self.inner)?; + let mut items = crate::table::KeyValuePairs::new(); + let kv = crate::table::TableKeyValue::new( + crate::Key::new(self.variant), + crate::Item::Value(inner), + ); + items.insert(crate::InternalString::from(self.variant), kv); + Ok(crate::Value::InlineTable(crate::InlineTable::with_pairs( + items, + ))) + } +} diff --git a/vendor/toml_edit/src/ser/mod.rs b/vendor/toml_edit/src/ser/mod.rs index 2c310206b..7f9993027 100644 --- a/vendor/toml_edit/src/ser/mod.rs +++ b/vendor/toml_edit/src/ser/mod.rs @@ -24,7 +24,7 @@ pub enum Error { OutOfRange(Option<&'static str>), /// `None` could not be serialized to TOML UnsupportedNone, - /// Key was not convertable to `String` for serializing to TOML + /// Key was not convertible to `String` for serializing to TOML KeyNotString, /// A serialized date was invalid DateInvalid, diff --git a/vendor/toml_edit/src/ser/value.rs b/vendor/toml_edit/src/ser/value.rs index d29390a4c..47a17a3b1 100644 --- a/vendor/toml_edit/src/ser/value.rs +++ b/vendor/toml_edit/src/ser/value.rs @@ -60,10 +60,10 @@ impl serde::ser::Serializer for ValueSerializer { type SerializeSeq = super::SerializeValueArray; type SerializeTuple = super::SerializeValueArray; type SerializeTupleStruct = super::SerializeValueArray; - type SerializeTupleVariant = super::SerializeValueArray; + type SerializeTupleVariant = super::SerializeTupleVariant; type SerializeMap = super::SerializeMap; type SerializeStruct = super::SerializeMap; - type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>; + type SerializeStructVariant = super::SerializeStructVariant; fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> { Ok(v.into()) @@ -108,7 +108,17 @@ impl serde::ser::Serializer for ValueSerializer { self.serialize_f64(v as f64) } - fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> { + fn serialize_f64(self, mut v: f64) -> Result<Self::Ok, Self::Error> { + // Discard sign of NaN when serialized using Serde. + // + // In all likelihood the sign of NaNs is not meaningful in the user's + // program. Ending up with `-nan` in the TOML document would usually be + // surprising and undesirable, when the sign of the NaN was not + // intentionally controlled by the caller, or may even be + // nondeterministic if it comes from arithmetic operations or a cast. + if v.is_nan() { + v = v.copysign(1.0); + } Ok(v.into()) } @@ -205,10 +215,10 @@ impl serde::ser::Serializer for ValueSerializer { self, _name: &'static str, _variant_index: u32, - _variant: &'static str, + variant: &'static str, len: usize, ) -> Result<Self::SerializeTupleVariant, Self::Error> { - self.serialize_seq(Some(len)) + Ok(super::SerializeTupleVariant::tuple(variant, len)) } fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { @@ -233,11 +243,11 @@ impl serde::ser::Serializer for ValueSerializer { fn serialize_struct_variant( self, - name: &'static str, + _name: &'static str, _variant_index: u32, - _variant: &'static str, - _len: usize, + variant: &'static str, + len: usize, ) -> Result<Self::SerializeStructVariant, Self::Error> { - Err(Error::UnsupportedType(Some(name))) + Ok(super::SerializeStructVariant::struct_(variant, len)) } } diff --git a/vendor/toml_edit/src/table.rs b/vendor/toml_edit/src/table.rs index 45d6d61b6..893028903 100644 --- a/vendor/toml_edit/src/table.rs +++ b/vendor/toml_edit/src/table.rs @@ -70,10 +70,10 @@ impl Table { values } - fn append_values<'s, 'c>( + fn append_values<'s>( &'s self, parent: &[&'s Key], - values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>, + values: &mut Vec<(Vec<&'s Key>, &'s Value)>, ) { for value in self.items.values() { let mut path = parent.to_vec(); @@ -474,7 +474,7 @@ fn decorate_table(table: &mut Table) { for (key_decor, value) in table .items .iter_mut() - .filter(|&(_, ref kv)| kv.value.is_value()) + .filter(|(_, kv)| kv.value.is_value()) .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap())) { key_decor.clear(); diff --git a/vendor/toml_edit/src/value.rs b/vendor/toml_edit/src/value.rs index f10da9a4c..62eb30c7a 100644 --- a/vendor/toml_edit/src/value.rs +++ b/vendor/toml_edit/src/value.rs @@ -284,6 +284,7 @@ impl From<i64> for Value { impl From<f64> for Value { fn from(f: f64) -> Self { + // Preserve sign of NaN. It may get written to TOML as `-nan`. Value::Float(Formatted::new(f)) } } |