Merge pull request #308 from ehuss/edition-2018

Migrate to 2018 edition
This commit is contained in:
Alex Crichton 2019-05-09 06:49:11 -07:00 committed by GitHub
commit e769341003
27 changed files with 999 additions and 694 deletions

View file

@ -14,6 +14,7 @@ implementations of the standard Serialize/Deserialize traits for TOML data to
facilitate deserializing and serializing Rust structures. facilitate deserializing and serializing Rust structures.
""" """
categories = ["config", "encoding", "parser-implementations"] categories = ["config", "encoding", "parser-implementations"]
edition = "2018"
[workspace] [workspace]
members = ['test-suite'] members = ['test-suite']

View file

@ -3,9 +3,7 @@
#![deny(warnings)] #![deny(warnings)]
extern crate toml; use serde_derive::Deserialize;
#[macro_use]
extern crate serde_derive;
/// This is what we're going to decode into. Each field is optional, meaning /// This is what we're going to decode into. Each field is optional, meaning
/// that it doesn't have to be present in TOML. /// that it doesn't have to be present in TOML.

View file

@ -3,9 +3,7 @@
#![deny(warnings)] #![deny(warnings)]
extern crate toml; use serde_derive::Deserialize;
#[macro_use]
extern crate serde_derive;
/// This is what we're going to decode into. /// This is what we're going to decode into.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]

View file

@ -1,8 +1,5 @@
#![deny(warnings)] #![deny(warnings)]
extern crate serde_json;
extern crate toml;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io; use std::io;

View file

@ -65,13 +65,13 @@ enum Offset {
} }
impl fmt::Debug for Datetime { impl fmt::Debug for Datetime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f) fmt::Display::fmt(self, f)
} }
} }
impl fmt::Display for Datetime { impl fmt::Display for Datetime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(ref date) = self.date { if let Some(ref date) = self.date {
write!(f, "{}", date)?; write!(f, "{}", date)?;
} }
@ -89,13 +89,13 @@ impl fmt::Display for Datetime {
} }
impl fmt::Display for Date { impl fmt::Display for Date {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:04}-{:02}-{:02}", self.year, self.month, self.day) write!(f, "{:04}-{:02}-{:02}", self.year, self.month, self.day)
} }
} }
impl fmt::Display for Time { impl fmt::Display for Time {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:02}:{:02}:{:02}", self.hour, self.minute, self.second)?; write!(f, "{:02}:{:02}:{:02}", self.hour, self.minute, self.second)?;
if self.nanosecond != 0 { if self.nanosecond != 0 {
let s = format!("{:09}", self.nanosecond); let s = format!("{:09}", self.nanosecond);
@ -106,7 +106,7 @@ impl fmt::Display for Time {
} }
impl fmt::Display for Offset { impl fmt::Display for Offset {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self { match *self {
Offset::Z => write!(f, "Z"), Offset::Z => write!(f, "Z"),
Offset::Custom { hours, minutes } => write!(f, "{:+03}:{:02}", hours, minutes), Offset::Custom { hours, minutes } => write!(f, "{:+03}:{:02}", hours, minutes),
@ -207,7 +207,7 @@ impl FromStr for Datetime {
let mut end = whole.len(); let mut end = whole.len();
for (i, byte) in whole.bytes().enumerate() { for (i, byte) in whole.bytes().enumerate() {
match byte { match byte {
b'0'...b'9' => { b'0'..=b'9' => {
if i < 9 { if i < 9 {
let p = 10_u32.pow(8 - i as u32); let p = 10_u32.pow(8 - i as u32);
nanosecond += p * (byte - b'0') as u32; nanosecond += p * (byte - b'0') as u32;
@ -298,7 +298,7 @@ impl FromStr for Datetime {
} }
} }
fn digit(chars: &mut str::Chars) -> Result<u8, DatetimeParseError> { fn digit(chars: &mut str::Chars<'_>) -> Result<u8, DatetimeParseError> {
match chars.next() { match chars.next() {
Some(c) if '0' <= c && c <= '9' => Ok(c as u8 - b'0'), Some(c) if '0' <= c && c <= '9' => Ok(c as u8 - b'0'),
_ => Err(DatetimeParseError { _private: () }), _ => Err(DatetimeParseError { _private: () }),
@ -328,7 +328,7 @@ impl<'de> de::Deserialize<'de> for Datetime {
impl<'de> de::Visitor<'de> for DatetimeVisitor { impl<'de> de::Visitor<'de> for DatetimeVisitor {
type Value = Datetime; type Value = Datetime;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a TOML datetime") formatter.write_str("a TOML datetime")
} }
@ -362,7 +362,7 @@ impl<'de> de::Deserialize<'de> for DatetimeKey {
impl<'de> de::Visitor<'de> for FieldVisitor { impl<'de> de::Visitor<'de> for FieldVisitor {
type Value = (); type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a valid datetime field") formatter.write_str("a valid datetime field")
} }
@ -397,7 +397,7 @@ impl<'de> de::Deserialize<'de> for DatetimeFromString {
impl<'de> de::Visitor<'de> for Visitor { impl<'de> de::Visitor<'de> for Visitor {
type Value = DatetimeFromString; type Value = DatetimeFromString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("string containing a datetime") formatter.write_str("string containing a datetime")
} }
@ -417,7 +417,7 @@ impl<'de> de::Deserialize<'de> for DatetimeFromString {
} }
impl fmt::Display for DatetimeParseError { impl fmt::Display for DatetimeParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"failed to parse datetime".fmt(f) "failed to parse datetime".fmt(f)
} }
} }

View file

@ -15,9 +15,9 @@ use serde::de;
use serde::de::value::BorrowedStrDeserializer; use serde::de::value::BorrowedStrDeserializer;
use serde::de::IntoDeserializer; use serde::de::IntoDeserializer;
use datetime; use crate::datetime;
use spanned; use crate::spanned;
use tokens::{Error as TokenError, Span, Token, Tokenizer}; use crate::tokens::{Error as TokenError, Span, Token, Tokenizer};
/// Deserializes a byte slice into a type. /// Deserializes a byte slice into a type.
/// ///
@ -41,9 +41,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #[macro_use] /// use serde_derive::Deserialize;
/// extern crate serde_derive;
/// extern crate toml;
/// ///
/// #[derive(Deserialize)] /// #[derive(Deserialize)]
/// struct Config { /// struct Config {
@ -265,7 +263,7 @@ impl<'de, 'b> de::Deserializer<'de> for &'b mut Deserializer<'de> {
} }
} }
forward_to_deserialize_any! { serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map struct unit newtype_struct bytes byte_buf map struct unit newtype_struct
ignored_any unit_struct tuple_struct tuple option identifier ignored_any unit_struct tuple_struct tuple option identifier
@ -495,7 +493,7 @@ impl<'de, 'b> de::Deserializer<'de> for MapVisitor<'de, 'b> {
visitor.visit_newtype_struct(self) visitor.visit_newtype_struct(self)
} }
forward_to_deserialize_any! { serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map struct unit identifier bytes byte_buf map struct unit identifier
ignored_any unit_struct tuple_struct tuple enum ignored_any unit_struct tuple_struct tuple enum
@ -525,7 +523,7 @@ impl<'de> de::Deserializer<'de> for StrDeserializer<'de> {
} }
} }
forward_to_deserialize_any! { serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map struct option unit newtype_struct bytes byte_buf map struct option unit newtype_struct
ignored_any unit_struct tuple_struct tuple enum identifier ignored_any unit_struct tuple_struct tuple enum identifier
@ -699,7 +697,7 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> {
visitor.visit_newtype_struct(self) visitor.visit_newtype_struct(self)
} }
forward_to_deserialize_any! { serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map unit identifier bytes byte_buf map unit identifier
ignored_any unit_struct tuple_struct tuple ignored_any unit_struct tuple_struct tuple
@ -796,7 +794,7 @@ impl<'de> de::Deserializer<'de> for DatetimeFieldDeserializer {
visitor.visit_borrowed_str(datetime::FIELD) visitor.visit_borrowed_str(datetime::FIELD)
} }
forward_to_deserialize_any! { serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map struct option unit newtype_struct bytes byte_buf map struct option unit newtype_struct
ignored_any unit_struct tuple_struct tuple enum identifier ignored_any unit_struct tuple_struct tuple enum identifier
@ -1520,7 +1518,7 @@ impl<'a> Deserializer<'a> {
fn array(&mut self) -> Result<(Span, Vec<Value<'a>>), Error> { fn array(&mut self) -> Result<(Span, Vec<Value<'a>>), Error> {
let mut ret = Vec::new(); let mut ret = Vec::new();
let intermediate = |me: &mut Deserializer| { let intermediate = |me: &mut Deserializer<'_>| {
loop { loop {
me.eat_whitespace()?; me.eat_whitespace()?;
if !me.eat(Token::Newline)? && !me.eat_comment()? { if !me.eat(Token::Newline)? && !me.eat_comment()? {
@ -1775,7 +1773,7 @@ impl Error {
} }
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.inner.kind { match self.inner.kind {
ErrorKind::UnexpectedEof => "unexpected eof encountered".fmt(f)?, ErrorKind::UnexpectedEof => "unexpected eof encountered".fmt(f)?,
ErrorKind::InvalidCharInString(c) => write!( ErrorKind::InvalidCharInString(c) => write!(

View file

@ -77,9 +77,7 @@
//! An example of deserializing with TOML is: //! An example of deserializing with TOML is:
//! //!
//! ```rust //! ```rust
//! #[macro_use] //! use serde_derive::Deserialize;
//! extern crate serde_derive;
//! extern crate toml;
//! //!
//! #[derive(Deserialize)] //! #[derive(Deserialize)]
//! struct Config { //! struct Config {
@ -113,9 +111,7 @@
//! You can serialize types in a similar fashion: //! You can serialize types in a similar fashion:
//! //!
//! ```rust //! ```rust
//! #[macro_use] //! use serde_derive::Serialize;
//! extern crate serde_derive;
//! extern crate toml;
//! //!
//! #[derive(Serialize)] //! #[derive(Serialize)]
//! struct Config { //! struct Config {
@ -150,24 +146,20 @@
#![doc(html_root_url = "https://docs.rs/toml/0.5")] #![doc(html_root_url = "https://docs.rs/toml/0.5")]
#![deny(missing_docs)] #![deny(missing_docs)]
#![warn(rust_2018_idioms)]
#[macro_use]
extern crate serde;
#[cfg(feature = "preserve_order")]
extern crate linked_hash_map;
pub mod map; pub mod map;
pub mod value; pub mod value;
#[doc(no_inline)] #[doc(no_inline)]
pub use value::Value; pub use crate::value::Value;
mod datetime; mod datetime;
pub mod ser; pub mod ser;
#[doc(no_inline)] #[doc(no_inline)]
pub use ser::{to_string, to_string_pretty, to_vec, Serializer}; pub use crate::ser::{to_string, to_string_pretty, to_vec, Serializer};
pub mod de; pub mod de;
#[doc(no_inline)] #[doc(no_inline)]
pub use de::{from_slice, from_str, Deserializer}; pub use crate::de::{from_slice, from_str, Deserializer};
mod tokens; mod tokens;
#[doc(hidden)] #[doc(hidden)]
@ -175,4 +167,4 @@ pub mod macros;
mod spanned; mod spanned;
#[doc(no_inline)] #[doc(no_inline)]
pub use spanned::Spanned; pub use crate::spanned::Spanned;

View file

@ -1,17 +1,14 @@
pub use serde::de::{Deserialize, IntoDeserializer}; pub use serde::de::{Deserialize, IntoDeserializer};
use value::{Array, Table, Value}; use crate::value::{Array, Table, Value};
/// Construct a [`toml::Value`] from TOML syntax. /// Construct a [`toml::Value`] from TOML syntax.
/// ///
/// [`toml::Value`]: value/enum.Value.html /// [`toml::Value`]: value/enum.Value.html
/// ///
/// ```rust /// ```rust
/// #[macro_use]
/// extern crate toml;
///
/// fn main() { /// fn main() {
/// let cargo_toml = toml! { /// let cargo_toml = toml::toml! {
/// [package] /// [package]
/// name = "toml" /// name = "toml"
/// version = "0.4.5" /// version = "0.4.5"

View file

@ -14,12 +14,12 @@
//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html //! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
//! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html //! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
use crate::value::Value;
use serde::{de, ser}; use serde::{de, ser};
use std::borrow::Borrow;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use value::Value;
use std::hash::Hash; use std::hash::Hash;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::borrow::Borrow;
use std::ops; use std::ops;
#[cfg(not(feature = "preserve_order"))] #[cfg(not(feature = "preserve_order"))]
@ -140,14 +140,14 @@ impl Map<String, Value> {
/// Gets the given key's corresponding entry in the map for in-place /// Gets the given key's corresponding entry in the map for in-place
/// manipulation. /// manipulation.
pub fn entry<S>(&mut self, key: S) -> Entry pub fn entry<S>(&mut self, key: S) -> Entry<'_>
where where
S: Into<String>, S: Into<String>,
{ {
#[cfg(not(feature = "preserve_order"))]
use std::collections::btree_map::Entry as EntryImpl;
#[cfg(feature = "preserve_order")] #[cfg(feature = "preserve_order")]
use linked_hash_map::Entry as EntryImpl; use linked_hash_map::Entry as EntryImpl;
#[cfg(not(feature = "preserve_order"))]
use std::collections::btree_map::Entry as EntryImpl;
match self.map.entry(key.into()) { match self.map.entry(key.into()) {
EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }), EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }),
@ -169,7 +169,7 @@ impl Map<String, Value> {
/// Gets an iterator over the entries of the map. /// Gets an iterator over the entries of the map.
#[inline] #[inline]
pub fn iter(&self) -> Iter { pub fn iter(&self) -> Iter<'_> {
Iter { Iter {
iter: self.map.iter(), iter: self.map.iter(),
} }
@ -177,7 +177,7 @@ impl Map<String, Value> {
/// Gets a mutable iterator over the entries of the map. /// Gets a mutable iterator over the entries of the map.
#[inline] #[inline]
pub fn iter_mut(&mut self) -> IterMut { pub fn iter_mut(&mut self) -> IterMut<'_> {
IterMut { IterMut {
iter: self.map.iter_mut(), iter: self.map.iter_mut(),
} }
@ -185,7 +185,7 @@ impl Map<String, Value> {
/// Gets an iterator over the keys of the map. /// Gets an iterator over the keys of the map.
#[inline] #[inline]
pub fn keys(&self) -> Keys { pub fn keys(&self) -> Keys<'_> {
Keys { Keys {
iter: self.map.keys(), iter: self.map.keys(),
} }
@ -193,7 +193,7 @@ impl Map<String, Value> {
/// Gets an iterator over the values of the map. /// Gets an iterator over the values of the map.
#[inline] #[inline]
pub fn values(&self) -> Values { pub fn values(&self) -> Values<'_> {
Values { Values {
iter: self.map.values(), iter: self.map.values(),
} }
@ -253,7 +253,7 @@ where
impl Debug for Map<String, Value> { impl Debug for Map<String, Value> {
#[inline] #[inline]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.map.fmt(formatter) self.map.fmt(formatter)
} }
} }
@ -265,10 +265,10 @@ impl ser::Serialize for Map<String, Value> {
S: ser::Serializer, S: ser::Serializer,
{ {
use serde::ser::SerializeMap; use serde::ser::SerializeMap;
let mut map = try!(serializer.serialize_map(Some(self.len()))); let mut map = serializer.serialize_map(Some(self.len()))?;
for (k, v) in self { for (k, v) in self {
try!(map.serialize_key(k)); map.serialize_key(k)?;
try!(map.serialize_value(v)); map.serialize_value(v)?;
} }
map.end() map.end()
} }
@ -285,7 +285,7 @@ impl<'de> de::Deserialize<'de> for Map<String, Value> {
impl<'de> de::Visitor<'de> for Visitor { impl<'de> de::Visitor<'de> for Visitor {
type Value = Map<String, Value>; type Value = Map<String, Value>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a map") formatter.write_str("a map")
} }
@ -304,7 +304,7 @@ impl<'de> de::Deserialize<'de> for Map<String, Value> {
{ {
let mut values = Map::new(); let mut values = Map::new();
while let Some((key, value)) = try!(visitor.next_entry()) { while let Some((key, value)) = visitor.next_entry()? {
values.insert(key, value); values.insert(key, value);
} }

View file

@ -12,8 +12,7 @@
//! may use the `tables_last` function in this module like so: //! may use the `tables_last` function in this module like so:
//! //!
//! ```rust //! ```rust
//! # #[macro_use] extern crate serde_derive; //! # use serde_derive::Serialize;
//! # extern crate toml;
//! # use std::collections::HashMap; //! # use std::collections::HashMap;
//! #[derive(Serialize)] //! #[derive(Serialize)]
//! struct Manifest { //! struct Manifest {
@ -32,7 +31,7 @@ use std::fmt::{self, Write};
use std::marker; use std::marker;
use std::rc::Rc; use std::rc::Rc;
use datetime; use crate::datetime;
use serde::ser; use serde::ser;
/// Serialize the given data structure as a TOML byte vector. /// Serialize the given data structure as a TOML byte vector.
@ -56,9 +55,7 @@ where
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #[macro_use] /// use serde_derive::Serialize;
/// extern crate serde_derive;
/// extern crate toml;
/// ///
/// #[derive(Serialize)] /// #[derive(Serialize)]
/// struct Config { /// struct Config {
@ -442,7 +439,7 @@ impl<'a> Serializer<'a> {
} }
// recursive implementation of `emit_key` above // recursive implementation of `emit_key` above
fn _emit_key(&mut self, state: &State) -> Result<(), Error> { fn _emit_key(&mut self, state: &State<'_>) -> Result<(), Error> {
match *state { match *state {
State::End => Ok(()), State::End => Ok(()),
State::Array { State::Array {
@ -479,7 +476,7 @@ impl<'a> Serializer<'a> {
fn emit_array(&mut self, first: &Cell<bool>, len: Option<usize>) -> Result<(), Error> { fn emit_array(&mut self, first: &Cell<bool>, len: Option<usize>) -> Result<(), Error> {
match (len, &self.settings.array) { match (len, &self.settings.array) {
(Some(0...1), _) | (_, &None) => { (Some(0..=1), _) | (_, &None) => {
if first.get() { if first.get() {
self.dst.push_str("[") self.dst.push_str("[")
} else { } else {
@ -517,7 +514,7 @@ impl<'a> Serializer<'a> {
fn escape_key(&mut self, key: &str) -> Result<(), Error> { fn escape_key(&mut self, key: &str) -> Result<(), Error> {
let ok = key.chars().all(|c| match c { let ok = key.chars().all(|c| match c {
'a'...'z' | 'A'...'Z' | '0'...'9' | '-' | '_' => true, 'a'..='z' | 'A'..='Z' | '0'..='9' | '-' | '_' => true,
_ => false, _ => false,
}); });
if ok { if ok {
@ -666,7 +663,7 @@ impl<'a> Serializer<'a> {
Ok(()) Ok(())
} }
fn emit_table_header(&mut self, state: &State) -> Result<(), Error> { fn emit_table_header(&mut self, state: &State<'_>) -> Result<(), Error> {
let array_of_tables = match *state { let array_of_tables = match *state {
State::End => return Ok(()), State::End => return Ok(()),
State::Array { .. } => true, State::Array { .. } => true,
@ -730,7 +727,7 @@ impl<'a> Serializer<'a> {
Ok(()) Ok(())
} }
fn emit_key_part(&mut self, key: &State) -> Result<bool, Error> { fn emit_key_part(&mut self, key: &State<'_>) -> Result<bool, Error> {
match *key { match *key {
State::Array { parent, .. } => self.emit_key_part(parent), State::Array { parent, .. } => self.emit_key_part(parent),
State::End => Ok(true), State::End => Ok(true),
@ -997,7 +994,7 @@ impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> {
match self.type_.get() { match self.type_.get() {
Some("table") => return Ok(()), Some("table") => return Ok(()),
Some(_) => match (self.len, &self.ser.settings.array) { Some(_) => match (self.len, &self.ser.settings.array) {
(Some(0...1), _) | (_, &None) => { (Some(0..=1), _) | (_, &None) => {
self.ser.dst.push_str("]"); self.ser.dst.push_str("]");
} }
(_, &Some(ref a)) => { (_, &Some(ref a)) => {
@ -1531,7 +1528,7 @@ impl ser::Serializer for StringExtractor {
} }
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self { match *self {
Error::UnsupportedType => "unsupported Rust type".fmt(f), Error::UnsupportedType => "unsupported Rust type".fmt(f),
Error::KeyNotString => "map key was not a string".fmt(f), Error::KeyNotString => "map key was not a string".fmt(f),
@ -1584,8 +1581,7 @@ enum Category {
/// helper can be used like so: /// helper can be used like so:
/// ///
/// ```rust /// ```rust
/// # #[macro_use] extern crate serde_derive; /// # use serde_derive::Serialize;
/// # extern crate toml;
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// #[derive(Serialize)] /// #[derive(Serialize)]
/// struct Manifest { /// struct Manifest {

View file

@ -1,8 +1,5 @@
//! ``` //! ```
//! #[macro_use] //! use serde_derive::Deserialize;
//! extern crate serde_derive;
//!
//! extern crate toml;
//! use toml::Spanned; //! use toml::Spanned;
//! //!
//! #[derive(Deserialize)] //! #[derive(Deserialize)]
@ -93,7 +90,7 @@ where
{ {
type Value = Spanned<T>; type Value = Spanned<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a TOML spanned") formatter.write_str("a TOML spanned")
} }

View file

@ -294,8 +294,8 @@ impl<'a> Tokenizer<'a> {
&mut self, &mut self,
delim: char, delim: char,
start: usize, start: usize,
new_ch: &mut FnMut( new_ch: &mut dyn FnMut(
&mut Tokenizer, &mut Tokenizer<'_>,
&mut MaybeString, &mut MaybeString,
bool, bool,
usize, usize,
@ -514,7 +514,7 @@ impl MaybeString {
} }
} }
fn into_cow(self, input: &str) -> Cow<str> { fn into_cow(self, input: &str) -> Cow<'_, str> {
match self { match self {
MaybeString::NotEscaped(start) => Cow::Borrowed(&input[start..]), MaybeString::NotEscaped(start) => Cow::Borrowed(&input[start..]),
MaybeString::Owned(s) => Cow::Owned(s), MaybeString::Owned(s) => Cow::Owned(s),
@ -665,9 +665,9 @@ mod tests {
#[test] #[test]
fn all() { fn all() {
fn t(input: &str, expected: &[((usize, usize), Token, &str)]) { fn t(input: &str, expected: &[((usize, usize), Token<'_>, &str)]) {
let mut tokens = Tokenizer::new(input); let mut tokens = Tokenizer::new(input);
let mut actual: Vec<((usize, usize), Token, &str)> = Vec::new(); let mut actual: Vec<((usize, usize), Token<'_>, &str)> = Vec::new();
while let Some((span, token)) = tokens.next().unwrap() { while let Some((span, token)) = tokens.next().unwrap() {
actual.push((span.into(), token, &input[span.start..span.end])); actual.push((span.into(), token, &input[span.start..span.end]));
} }

View file

@ -11,11 +11,10 @@ use serde::de;
use serde::de::IntoDeserializer; use serde::de::IntoDeserializer;
use serde::ser; use serde::ser;
use datetime::{self, DatetimeFromString}; use crate::datetime::{self, DatetimeFromString};
pub use datetime::{Datetime, DatetimeParseError}; pub use crate::datetime::{Datetime, DatetimeParseError};
pub use map::Map;
pub use crate::map::Map;
/// Representation of a TOML value. /// Representation of a TOML value.
#[derive(PartialEq, Clone, Debug)] #[derive(PartialEq, Clone, Debug)]
@ -50,7 +49,7 @@ impl Value {
/// ///
/// This conversion can fail if `T`'s implementation of `Serialize` decides to /// This conversion can fail if `T`'s implementation of `Serialize` decides to
/// fail, or if `T` contains a map with non-string keys. /// fail, or if `T` contains a map with non-string keys.
pub fn try_from<T>(value: T) -> Result<Value, ::ser::Error> pub fn try_from<T>(value: T) -> Result<Value, crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
@ -66,7 +65,7 @@ impl Value {
/// something is wrong with the data, for example required struct fields are /// something is wrong with the data, for example required struct fields are
/// missing from the TOML map or some number is too big to fit in the expected /// missing from the TOML map or some number is too big to fit in the expected
/// primitive type. /// primitive type.
pub fn try_into<'de, T>(self) -> Result<T, ::de::Error> pub fn try_into<'de, T>(self) -> Result<T, crate::de::Error>
where where
T: de::Deserialize<'de>, T: de::Deserialize<'de>,
{ {
@ -391,17 +390,17 @@ where
} }
impl fmt::Display for Value { impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
::ser::to_string(self) crate::ser::to_string(self)
.expect("Unable to represent value as string") .expect("Unable to represent value as string")
.fmt(f) .fmt(f)
} }
} }
impl FromStr for Value { impl FromStr for Value {
type Err = ::de::Error; type Err = crate::de::Error;
fn from_str(s: &str) -> Result<Value, Self::Err> { fn from_str(s: &str) -> Result<Value, Self::Err> {
::from_str(s) crate::from_str(s)
} }
} }
@ -462,7 +461,7 @@ impl<'de> de::Deserialize<'de> for Value {
impl<'de> de::Visitor<'de> for ValueVisitor { impl<'de> de::Visitor<'de> for ValueVisitor {
type Value = Value; type Value = Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("any valid TOML value") formatter.write_str("any valid TOML value")
} }
@ -552,9 +551,9 @@ impl<'de> de::Deserialize<'de> for Value {
} }
impl<'de> de::Deserializer<'de> for Value { impl<'de> de::Deserializer<'de> for Value {
type Error = ::de::Error; type Error = crate::de::Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, ::de::Error> fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, crate::de::Error>
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
@ -595,7 +594,7 @@ impl<'de> de::Deserializer<'de> for Value {
_name: &str, _name: &str,
_variants: &'static [&'static str], _variants: &'static [&'static str],
visitor: V, visitor: V,
) -> Result<V::Value, ::de::Error> ) -> Result<V::Value, crate::de::Error>
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
@ -610,7 +609,7 @@ impl<'de> de::Deserializer<'de> for Value {
// `None` is interpreted as a missing field so be sure to implement `Some` // `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field. // as a present field.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, ::de::Error> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, crate::de::Error>
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
@ -621,14 +620,14 @@ impl<'de> de::Deserializer<'de> for Value {
self, self,
_name: &'static str, _name: &'static str,
visitor: V, visitor: V,
) -> Result<V::Value, ::de::Error> ) -> Result<V::Value, crate::de::Error>
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
visitor.visit_newtype_struct(self) visitor.visit_newtype_struct(self)
} }
forward_to_deserialize_any! { serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
bytes byte_buf map unit_struct tuple_struct struct bytes byte_buf map unit_struct tuple_struct struct
tuple ignored_any identifier tuple ignored_any identifier
@ -648,9 +647,9 @@ impl SeqDeserializer {
} }
impl<'de> de::SeqAccess<'de> for SeqDeserializer { impl<'de> de::SeqAccess<'de> for SeqDeserializer {
type Error = ::de::Error; type Error = crate::de::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, ::de::Error> fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, crate::de::Error>
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
@ -683,9 +682,9 @@ impl MapDeserializer {
} }
impl<'de> de::MapAccess<'de> for MapDeserializer { impl<'de> de::MapAccess<'de> for MapDeserializer {
type Error = ::de::Error; type Error = crate::de::Error;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, ::de::Error> fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, crate::de::Error>
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
@ -698,7 +697,7 @@ impl<'de> de::MapAccess<'de> for MapDeserializer {
} }
} }
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, ::de::Error> fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, crate::de::Error>
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
@ -720,7 +719,7 @@ impl<'de> de::MapAccess<'de> for MapDeserializer {
} }
} }
impl<'de> de::IntoDeserializer<'de, ::de::Error> for Value { impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Value {
type Deserializer = Self; type Deserializer = Self;
fn into_deserializer(self) -> Self { fn into_deserializer(self) -> Self {
@ -732,7 +731,7 @@ struct Serializer;
impl ser::Serializer for Serializer { impl ser::Serializer for Serializer {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
type SerializeSeq = SerializeVec; type SerializeSeq = SerializeVec;
type SerializeTuple = SerializeVec; type SerializeTuple = SerializeVec;
@ -740,41 +739,41 @@ impl ser::Serializer for Serializer {
type SerializeTupleVariant = SerializeVec; type SerializeTupleVariant = SerializeVec;
type SerializeMap = SerializeMap; type SerializeMap = SerializeMap;
type SerializeStruct = SerializeMap; type SerializeStruct = SerializeMap;
type SerializeStructVariant = ser::Impossible<Value, ::ser::Error>; type SerializeStructVariant = ser::Impossible<Value, crate::ser::Error>;
fn serialize_bool(self, value: bool) -> Result<Value, ::ser::Error> { fn serialize_bool(self, value: bool) -> Result<Value, crate::ser::Error> {
Ok(Value::Boolean(value)) Ok(Value::Boolean(value))
} }
fn serialize_i8(self, value: i8) -> Result<Value, ::ser::Error> { fn serialize_i8(self, value: i8) -> Result<Value, crate::ser::Error> {
self.serialize_i64(value.into()) self.serialize_i64(value.into())
} }
fn serialize_i16(self, value: i16) -> Result<Value, ::ser::Error> { fn serialize_i16(self, value: i16) -> Result<Value, crate::ser::Error> {
self.serialize_i64(value.into()) self.serialize_i64(value.into())
} }
fn serialize_i32(self, value: i32) -> Result<Value, ::ser::Error> { fn serialize_i32(self, value: i32) -> Result<Value, crate::ser::Error> {
self.serialize_i64(value.into()) self.serialize_i64(value.into())
} }
fn serialize_i64(self, value: i64) -> Result<Value, ::ser::Error> { fn serialize_i64(self, value: i64) -> Result<Value, crate::ser::Error> {
Ok(Value::Integer(value.into())) Ok(Value::Integer(value.into()))
} }
fn serialize_u8(self, value: u8) -> Result<Value, ::ser::Error> { fn serialize_u8(self, value: u8) -> Result<Value, crate::ser::Error> {
self.serialize_i64(value.into()) self.serialize_i64(value.into())
} }
fn serialize_u16(self, value: u16) -> Result<Value, ::ser::Error> { fn serialize_u16(self, value: u16) -> Result<Value, crate::ser::Error> {
self.serialize_i64(value.into()) self.serialize_i64(value.into())
} }
fn serialize_u32(self, value: u32) -> Result<Value, ::ser::Error> { fn serialize_u32(self, value: u32) -> Result<Value, crate::ser::Error> {
self.serialize_i64(value.into()) self.serialize_i64(value.into())
} }
fn serialize_u64(self, value: u64) -> Result<Value, ::ser::Error> { fn serialize_u64(self, value: u64) -> Result<Value, crate::ser::Error> {
if value <= i64::max_value() as u64 { if value <= i64::max_value() as u64 {
self.serialize_i64(value as i64) self.serialize_i64(value as i64)
} else { } else {
@ -782,35 +781,35 @@ impl ser::Serializer for Serializer {
} }
} }
fn serialize_f32(self, value: f32) -> Result<Value, ::ser::Error> { fn serialize_f32(self, value: f32) -> Result<Value, crate::ser::Error> {
self.serialize_f64(value.into()) self.serialize_f64(value.into())
} }
fn serialize_f64(self, value: f64) -> Result<Value, ::ser::Error> { fn serialize_f64(self, value: f64) -> Result<Value, crate::ser::Error> {
Ok(Value::Float(value)) Ok(Value::Float(value))
} }
fn serialize_char(self, value: char) -> Result<Value, ::ser::Error> { fn serialize_char(self, value: char) -> Result<Value, crate::ser::Error> {
let mut s = String::new(); let mut s = String::new();
s.push(value); s.push(value);
self.serialize_str(&s) self.serialize_str(&s)
} }
fn serialize_str(self, value: &str) -> Result<Value, ::ser::Error> { fn serialize_str(self, value: &str) -> Result<Value, crate::ser::Error> {
Ok(Value::String(value.to_owned())) Ok(Value::String(value.to_owned()))
} }
fn serialize_bytes(self, value: &[u8]) -> Result<Value, ::ser::Error> { fn serialize_bytes(self, value: &[u8]) -> Result<Value, crate::ser::Error> {
let vec = value.iter().map(|&b| Value::Integer(b.into())).collect(); let vec = value.iter().map(|&b| Value::Integer(b.into())).collect();
Ok(Value::Array(vec)) Ok(Value::Array(vec))
} }
fn serialize_unit(self) -> Result<Value, ::ser::Error> { fn serialize_unit(self) -> Result<Value, crate::ser::Error> {
Err(::ser::Error::UnsupportedType) Err(crate::ser::Error::UnsupportedType)
} }
fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, ::ser::Error> { fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, crate::ser::Error> {
Err(::ser::Error::UnsupportedType) Err(crate::ser::Error::UnsupportedType)
} }
fn serialize_unit_variant( fn serialize_unit_variant(
@ -818,7 +817,7 @@ impl ser::Serializer for Serializer {
_name: &'static str, _name: &'static str,
_variant_index: u32, _variant_index: u32,
_variant: &'static str, _variant: &'static str,
) -> Result<Value, ::ser::Error> { ) -> Result<Value, crate::ser::Error> {
self.serialize_str(_variant) self.serialize_str(_variant)
} }
@ -826,7 +825,7 @@ impl ser::Serializer for Serializer {
self, self,
_name: &'static str, _name: &'static str,
value: &T, value: &T,
) -> Result<Value, ::ser::Error> ) -> Result<Value, crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
@ -839,31 +838,31 @@ impl ser::Serializer for Serializer {
_variant_index: u32, _variant_index: u32,
_variant: &'static str, _variant: &'static str,
_value: &T, _value: &T,
) -> Result<Value, ::ser::Error> ) -> Result<Value, crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
Err(::ser::Error::UnsupportedType) Err(crate::ser::Error::UnsupportedType)
} }
fn serialize_none(self) -> Result<Value, ::ser::Error> { fn serialize_none(self) -> Result<Value, crate::ser::Error> {
Err(::ser::Error::UnsupportedNone) Err(crate::ser::Error::UnsupportedNone)
} }
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, ::ser::Error> fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
value.serialize(self) value.serialize(self)
} }
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, ::ser::Error> { fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, crate::ser::Error> {
Ok(SerializeVec { Ok(SerializeVec {
vec: Vec::with_capacity(len.unwrap_or(0)), vec: Vec::with_capacity(len.unwrap_or(0)),
}) })
} }
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, ::ser::Error> { fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, crate::ser::Error> {
self.serialize_seq(Some(len)) self.serialize_seq(Some(len))
} }
@ -871,7 +870,7 @@ impl ser::Serializer for Serializer {
self, self,
_name: &'static str, _name: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeTupleStruct, ::ser::Error> { ) -> Result<Self::SerializeTupleStruct, crate::ser::Error> {
self.serialize_seq(Some(len)) self.serialize_seq(Some(len))
} }
@ -881,11 +880,11 @@ impl ser::Serializer for Serializer {
_variant_index: u32, _variant_index: u32,
_variant: &'static str, _variant: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeTupleVariant, ::ser::Error> { ) -> Result<Self::SerializeTupleVariant, crate::ser::Error> {
self.serialize_seq(Some(len)) self.serialize_seq(Some(len))
} }
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, ::ser::Error> { fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, crate::ser::Error> {
Ok(SerializeMap { Ok(SerializeMap {
map: Map::new(), map: Map::new(),
next_key: None, next_key: None,
@ -896,7 +895,7 @@ impl ser::Serializer for Serializer {
self, self,
_name: &'static str, _name: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeStruct, ::ser::Error> { ) -> Result<Self::SerializeStruct, crate::ser::Error> {
self.serialize_map(Some(len)) self.serialize_map(Some(len))
} }
@ -906,8 +905,8 @@ impl ser::Serializer for Serializer {
_variant_index: u32, _variant_index: u32,
_variant: &'static str, _variant: &'static str,
_len: usize, _len: usize,
) -> Result<Self::SerializeStructVariant, ::ser::Error> { ) -> Result<Self::SerializeStructVariant, crate::ser::Error> {
Err(::ser::Error::UnsupportedType) Err(crate::ser::Error::UnsupportedType)
} }
} }
@ -922,9 +921,9 @@ struct SerializeMap {
impl ser::SerializeSeq for SerializeVec { impl ser::SerializeSeq for SerializeVec {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
@ -932,75 +931,75 @@ impl ser::SerializeSeq for SerializeVec {
Ok(()) Ok(())
} }
fn end(self) -> Result<Value, ::ser::Error> { fn end(self) -> Result<Value, crate::ser::Error> {
Ok(Value::Array(self.vec)) Ok(Value::Array(self.vec))
} }
} }
impl ser::SerializeTuple for SerializeVec { impl ser::SerializeTuple for SerializeVec {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
ser::SerializeSeq::serialize_element(self, value) ser::SerializeSeq::serialize_element(self, value)
} }
fn end(self) -> Result<Value, ::ser::Error> { fn end(self) -> Result<Value, crate::ser::Error> {
ser::SerializeSeq::end(self) ser::SerializeSeq::end(self)
} }
} }
impl ser::SerializeTupleStruct for SerializeVec { impl ser::SerializeTupleStruct for SerializeVec {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
ser::SerializeSeq::serialize_element(self, value) ser::SerializeSeq::serialize_element(self, value)
} }
fn end(self) -> Result<Value, ::ser::Error> { fn end(self) -> Result<Value, crate::ser::Error> {
ser::SerializeSeq::end(self) ser::SerializeSeq::end(self)
} }
} }
impl ser::SerializeTupleVariant for SerializeVec { impl ser::SerializeTupleVariant for SerializeVec {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
ser::SerializeSeq::serialize_element(self, value) ser::SerializeSeq::serialize_element(self, value)
} }
fn end(self) -> Result<Value, ::ser::Error> { fn end(self) -> Result<Value, crate::ser::Error> {
ser::SerializeSeq::end(self) ser::SerializeSeq::end(self)
} }
} }
impl ser::SerializeMap for SerializeMap { impl ser::SerializeMap for SerializeMap {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), ::ser::Error> fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
match Value::try_from(key)? { match Value::try_from(key)? {
Value::String(s) => self.next_key = Some(s), Value::String(s) => self.next_key = Some(s),
_ => return Err(::ser::Error::KeyNotString), _ => return Err(crate::ser::Error::KeyNotString),
}; };
Ok(()) Ok(())
} }
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
@ -1010,26 +1009,26 @@ impl ser::SerializeMap for SerializeMap {
Ok(value) => { Ok(value) => {
self.map.insert(key, value); self.map.insert(key, value);
} }
Err(::ser::Error::UnsupportedNone) => {} Err(crate::ser::Error::UnsupportedNone) => {}
Err(e) => return Err(e), Err(e) => return Err(e),
} }
Ok(()) Ok(())
} }
fn end(self) -> Result<Value, ::ser::Error> { fn end(self) -> Result<Value, crate::ser::Error> {
Ok(Value::Table(self.map)) Ok(Value::Table(self.map))
} }
} }
impl ser::SerializeStruct for SerializeMap { impl ser::SerializeStruct for SerializeMap {
type Ok = Value; type Ok = Value;
type Error = ::ser::Error; type Error = crate::ser::Error;
fn serialize_field<T: ?Sized>( fn serialize_field<T: ?Sized>(
&mut self, &mut self,
key: &'static str, key: &'static str,
value: &T, value: &T,
) -> Result<(), ::ser::Error> ) -> Result<(), crate::ser::Error>
where where
T: ser::Serialize, T: ser::Serialize,
{ {
@ -1037,7 +1036,7 @@ impl ser::SerializeStruct for SerializeMap {
ser::SerializeMap::serialize_value(self, value) ser::SerializeMap::serialize_value(self, value)
} }
fn end(self) -> Result<Value, ::ser::Error> { fn end(self) -> Result<Value, crate::ser::Error> {
ser::SerializeMap::end(self) ser::SerializeMap::end(self)
} }
} }
@ -1060,7 +1059,7 @@ impl<'a, 'de> de::DeserializeSeed<'de> for DatetimeOrTable<'a> {
impl<'a, 'de> de::Visitor<'de> for DatetimeOrTable<'a> { impl<'a, 'de> de::Visitor<'de> for DatetimeOrTable<'a> {
type Value = bool; type Value = bool;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string key") formatter.write_str("a string key")
} }

View file

@ -3,6 +3,7 @@ name = "toml_test_suite"
version = "0.0.0" version = "0.0.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"] authors = ["Alex Crichton <alex@alexcrichton.com>"]
publish = false publish = false
edition = "2018"
[dev-dependencies] [dev-dependencies]
toml = { path = ".." } toml = { path = ".." }

View file

@ -1,5 +1,5 @@
extern crate toml;
extern crate serde; extern crate serde;
extern crate toml;
use serde::de::Deserialize; use serde::de::Deserialize;
@ -35,7 +35,10 @@ fn allow_duplicate_after_longer() {
let mut d = toml::de::Deserializer::new(s); let mut d = toml::de::Deserializer::new(s);
d.set_allow_duplicate_after_longer_table(true); d.set_allow_duplicate_after_longer_table(true);
let value = toml::Value::deserialize(&mut d).unwrap(); let value = toml::Value::deserialize(&mut d).unwrap();
assert_eq!(value["dependencies"]["openssl-sys"]["version"].as_integer(), Some(1)); assert_eq!(
value["dependencies"]["openssl-sys"]["version"].as_integer(),
Some(1)
);
assert_eq!(value["dependencies"]["libc"].as_integer(), Some(1)); assert_eq!(value["dependencies"]["libc"].as_integer(), Some(1));
assert_eq!(value["dependencies"]["bitflags"].as_integer(), Some(1)); assert_eq!(value["dependencies"]["bitflags"].as_integer(), Some(1));
} }

View file

@ -1,5 +1,6 @@
extern crate toml; extern crate toml;
#[macro_use] extern crate serde_derive; #[macro_use]
extern crate serde_derive;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Recipe { pub struct Recipe {
@ -8,41 +9,47 @@ pub struct Recipe {
#[serde(default)] #[serde(default)]
pub modules: Vec<Modules>, pub modules: Vec<Modules>,
#[serde(default)] #[serde(default)]
pub packages: Vec<Packages> pub packages: Vec<Packages>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Modules { pub struct Modules {
pub name: String, pub name: String,
pub version: Option<String> pub version: Option<String>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Packages { pub struct Packages {
pub name: String, pub name: String,
pub version: Option<String> pub version: Option<String>,
} }
#[test] #[test]
fn both_ends() { fn both_ends() {
let recipe_works = toml::from_str::<Recipe>(r#" let recipe_works = toml::from_str::<Recipe>(
r#"
name = "testing" name = "testing"
description = "example" description = "example"
modules = [] modules = []
[[packages]] [[packages]]
name = "base" name = "base"
"#).unwrap(); "#,
)
.unwrap();
toml::to_string(&recipe_works).unwrap(); toml::to_string(&recipe_works).unwrap();
let recipe_fails = toml::from_str::<Recipe>(r#" let recipe_fails = toml::from_str::<Recipe>(
r#"
name = "testing" name = "testing"
description = "example" description = "example"
packages = [] packages = []
[[modules]] [[modules]]
name = "base" name = "base"
"#).unwrap(); "#,
)
.unwrap();
let recipe_toml = toml::Value::try_from(recipe_fails).unwrap(); let recipe_toml = toml::Value::try_from(recipe_fails).unwrap();
recipe_toml.to_string(); recipe_toml.to_string();

View file

@ -1,7 +1,7 @@
extern crate toml; extern crate toml;
use toml::Value::{String, Integer, Float, Boolean, Array, Table};
use toml::map::Map; use toml::map::Map;
use toml::Value::{Array, Boolean, Float, Integer, String, Table};
macro_rules! map( ($($k:expr => $v:expr),*) => ({ macro_rules! map( ($($k:expr => $v:expr),*) => ({
let mut _m = Map::new(); let mut _m = Map::new();
@ -11,76 +11,86 @@ macro_rules! map( ($($k:expr => $v:expr),*) => ({
#[test] #[test]
fn simple_show() { fn simple_show() {
assert_eq!(String("foo".to_string()).to_string(), assert_eq!(String("foo".to_string()).to_string(), "\"foo\"");
"\"foo\""); assert_eq!(Integer(10).to_string(), "10");
assert_eq!(Integer(10).to_string(), assert_eq!(Float(10.0).to_string(), "10.0");
"10"); assert_eq!(Float(2.4).to_string(), "2.4");
assert_eq!(Float(10.0).to_string(), assert_eq!(Boolean(true).to_string(), "true");
"10.0"); assert_eq!(Array(vec![]).to_string(), "[]");
assert_eq!(Float(2.4).to_string(), assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string(), "[1, 2]");
"2.4");
assert_eq!(Boolean(true).to_string(),
"true");
assert_eq!(Array(vec![]).to_string(),
"[]");
assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string(),
"[1, 2]");
} }
#[test] #[test]
fn table() { fn table() {
assert_eq!(Table(map! { }).to_string(), assert_eq!(Table(map! {}).to_string(), "");
""); assert_eq!(
assert_eq!(Table(map! { Table(map! {
"test" => Integer(2), "test" => Integer(2),
"test2" => Integer(3) }).to_string(), "test2" => Integer(3) })
"test = 2\ntest2 = 3\n"); .to_string(),
assert_eq!(Table(map! { "test = 2\ntest2 = 3\n"
"test" => Integer(2), );
"test2" => Table(map! { assert_eq!(
"test" => String("wut".to_string()) Table(map! {
}) "test" => Integer(2),
}).to_string(), "test2" => Table(map! {
"test = 2\n\ "test" => String("wut".to_string())
\n\ })
[test2]\n\ })
test = \"wut\"\n"); .to_string(),
assert_eq!(Table(map! { "test = 2\n\
"test" => Integer(2), \n\
"test2" => Table(map! { [test2]\n\
"test" => String("wut".to_string()) test = \"wut\"\n"
}) );
}).to_string(), assert_eq!(
"test = 2\n\ Table(map! {
\n\ "test" => Integer(2),
[test2]\n\ "test2" => Table(map! {
test = \"wut\"\n"); "test" => String("wut".to_string())
assert_eq!(Table(map! { })
"test" => Integer(2), })
"test2" => Array(vec![Table(map! { .to_string(),
"test" => String("wut".to_string()) "test = 2\n\
})]) \n\
}).to_string(), [test2]\n\
"test = 2\n\ test = \"wut\"\n"
\n\ );
[[test2]]\n\ assert_eq!(
test = \"wut\"\n"); Table(map! {
assert_eq!(Table(map! { "test" => Integer(2),
"foo.bar" => Integer(2), "test2" => Array(vec![Table(map! {
"foo\"bar" => Integer(2) "test" => String("wut".to_string())
}).to_string(), })])
"\"foo\\\"bar\" = 2\n\ })
\"foo.bar\" = 2\n"); .to_string(),
assert_eq!(Table(map! { "test = 2\n\
"test" => Integer(2), \n\
"test2" => Array(vec![Table(map! { [[test2]]\n\
"test" => Array(vec![Integer(2)]) test = \"wut\"\n"
})]) );
}).to_string(), assert_eq!(
"test = 2\n\ Table(map! {
\n\ "foo.bar" => Integer(2),
[[test2]]\n\ "foo\"bar" => Integer(2)
test = [2]\n"); })
.to_string(),
"\"foo\\\"bar\" = 2\n\
\"foo.bar\" = 2\n"
);
assert_eq!(
Table(map! {
"test" => Integer(2),
"test2" => Array(vec![Table(map! {
"test" => Array(vec![Integer(2)])
})])
})
.to_string(),
"test = 2\n\
\n\
[[test2]]\n\
test = [2]\n"
);
let table = Table(map! { let table = Table(map! {
"test" => Integer(2), "test" => Integer(2),
"test2" => Array(vec![Table(map! { "test2" => Array(vec![Table(map! {
@ -88,15 +98,20 @@ fn table() {
Array(vec![String("foo".to_string()), String("bar".to_string())])]) Array(vec![String("foo".to_string()), String("bar".to_string())])])
})]) })])
}); });
assert_eq!(table.to_string(), assert_eq!(
"test = 2\n\ table.to_string(),
\n\ "test = 2\n\
[[test2]]\n\ \n\
test = [[2, 3], [\"foo\", \"bar\"]]\n"); [[test2]]\n\
assert_eq!(Table(map! { test = [[2, 3], [\"foo\", \"bar\"]]\n"
"test" => Array(vec![Integer(2)]), );
"test2" => Integer(2) assert_eq!(
}).to_string(), Table(map! {
"test = [2]\n\ "test" => Array(vec![Integer(2)]),
test2 = 2\n"); "test2" => Integer(2)
})
.to_string(),
"test = [2]\n\
test2 = 2\n"
);
} }

View file

@ -32,7 +32,9 @@ macro_rules! float_inf_tests {
# zero # zero
sf7 = +0.0 sf7 = +0.0
sf8 = -0.0 sf8 = -0.0
").expect("Parse infinities."); ",
)
.expect("Parse infinities.");
assert!(inf.sf1.is_infinite()); assert!(inf.sf1.is_infinite());
assert!(inf.sf1.is_sign_positive()); assert!(inf.sf1.is_sign_positive());
@ -55,8 +57,9 @@ macro_rules! float_inf_tests {
let s = toml::to_string(&inf).unwrap(); let s = toml::to_string(&inf).unwrap();
assert_eq!( assert_eq!(
s, "\ s,
sf1 = inf "\
sf1 = inf
sf2 = inf sf2 = inf
sf3 = -inf sf3 = -inf
sf4 = nan sf4 = nan

View file

@ -24,31 +24,33 @@ struct TwoUsers {
#[test] #[test]
fn no_unnecessary_newlines_array() { fn no_unnecessary_newlines_array() {
assert!(!to_string(&Users { assert!(!to_string(&Users {
user: vec![ user: vec![
User { User {
name: "John".to_string(), name: "John".to_string(),
surname: "Doe".to_string(), surname: "Doe".to_string(),
}, },
User { User {
name: "Jane".to_string(), name: "Jane".to_string(),
surname: "Dough".to_string(), surname: "Dough".to_string(),
}, },
], ],
}).unwrap() })
.starts_with("\n")); .unwrap()
.starts_with("\n"));
} }
#[test] #[test]
fn no_unnecessary_newlines_table() { fn no_unnecessary_newlines_table() {
assert!(!to_string(&TwoUsers { assert!(!to_string(&TwoUsers {
user0: User { user0: User {
name: "John".to_string(), name: "John".to_string(),
surname: "Doe".to_string(), surname: "Doe".to_string(),
}, },
user1: User { user1: User {
name: "Jane".to_string(), name: "Jane".to_string(),
surname: "Dough".to_string(), surname: "Dough".to_string(),
}, },
}).unwrap() })
.starts_with("\n")); .unwrap()
.starts_with("\n"));
} }

View file

@ -12,93 +12,156 @@ macro_rules! test( ($name:ident, $toml:expr) => (
fn $name() { run($toml); } fn $name() { run($toml); }
) ); ) );
test!(array_mixed_types_arrays_and_ints, test!(
include_str!("invalid/array-mixed-types-arrays-and-ints.toml")); array_mixed_types_arrays_and_ints,
test!(array_mixed_types_ints_and_floats, include_str!("invalid/array-mixed-types-arrays-and-ints.toml")
include_str!("invalid/array-mixed-types-ints-and-floats.toml")); );
test!(array_mixed_types_strings_and_ints, test!(
include_str!("invalid/array-mixed-types-strings-and-ints.toml")); array_mixed_types_ints_and_floats,
test!(datetime_malformed_no_leads, include_str!("invalid/array-mixed-types-ints-and-floats.toml")
include_str!("invalid/datetime-malformed-no-leads.toml")); );
test!(datetime_malformed_no_secs, test!(
include_str!("invalid/datetime-malformed-no-secs.toml")); array_mixed_types_strings_and_ints,
test!(datetime_malformed_no_t, include_str!("invalid/array-mixed-types-strings-and-ints.toml")
include_str!("invalid/datetime-malformed-no-t.toml")); );
test!(datetime_malformed_with_milli, test!(
include_str!("invalid/datetime-malformed-with-milli.toml")); datetime_malformed_no_leads,
test!(duplicate_key_table, include_str!("invalid/datetime-malformed-no-leads.toml")
include_str!("invalid/duplicate-key-table.toml")); );
test!(duplicate_keys, test!(
include_str!("invalid/duplicate-keys.toml")); datetime_malformed_no_secs,
test!(duplicate_table, include_str!("invalid/datetime-malformed-no-secs.toml")
include_str!("invalid/duplicate-table.toml")); );
test!(duplicate_tables, test!(
include_str!("invalid/duplicate-tables.toml")); datetime_malformed_no_t,
test!(empty_implicit_table, include_str!("invalid/datetime-malformed-no-t.toml")
include_str!("invalid/empty-implicit-table.toml")); );
test!(empty_table, test!(
include_str!("invalid/empty-table.toml")); datetime_malformed_with_milli,
test!(float_no_leading_zero, include_str!("invalid/datetime-malformed-with-milli.toml")
include_str!("invalid/float-no-leading-zero.toml")); );
test!(float_no_suffix, test!(
include_str!("invalid/float-no-suffix.toml")); duplicate_key_table,
test!(float_no_trailing_digits, include_str!("invalid/duplicate-key-table.toml")
include_str!("invalid/float-no-trailing-digits.toml")); );
test!(key_after_array, test!(duplicate_keys, include_str!("invalid/duplicate-keys.toml"));
include_str!("invalid/key-after-array.toml")); test!(
test!(key_after_table, duplicate_table,
include_str!("invalid/key-after-table.toml")); include_str!("invalid/duplicate-table.toml")
test!(key_empty, );
include_str!("invalid/key-empty.toml")); test!(
test!(key_hash, duplicate_tables,
include_str!("invalid/key-hash.toml")); include_str!("invalid/duplicate-tables.toml")
test!(key_newline, );
include_str!("invalid/key-newline.toml")); test!(
test!(key_open_bracket, empty_implicit_table,
include_str!("invalid/key-open-bracket.toml")); include_str!("invalid/empty-implicit-table.toml")
test!(key_single_open_bracket, );
include_str!("invalid/key-single-open-bracket.toml")); test!(empty_table, include_str!("invalid/empty-table.toml"));
test!(key_space, test!(
include_str!("invalid/key-space.toml")); float_no_leading_zero,
test!(key_start_bracket, include_str!("invalid/float-no-leading-zero.toml")
include_str!("invalid/key-start-bracket.toml")); );
test!(key_two_equals, test!(
include_str!("invalid/key-two-equals.toml")); float_no_suffix,
test!(string_bad_byte_escape, include_str!("invalid/float-no-suffix.toml")
include_str!("invalid/string-bad-byte-escape.toml")); );
test!(string_bad_escape, test!(
include_str!("invalid/string-bad-escape.toml")); float_no_trailing_digits,
test!(string_bad_line_ending_escape, include_str!("invalid/float-no-trailing-digits.toml")
include_str!("invalid/string-bad-line-ending-escape.toml")); );
test!(string_byte_escapes, test!(
include_str!("invalid/string-byte-escapes.toml")); key_after_array,
test!(string_no_close, include_str!("invalid/key-after-array.toml")
include_str!("invalid/string-no-close.toml")); );
test!(table_array_implicit, test!(
include_str!("invalid/table-array-implicit.toml")); key_after_table,
test!(table_array_malformed_bracket, include_str!("invalid/key-after-table.toml")
include_str!("invalid/table-array-malformed-bracket.toml")); );
test!(table_array_malformed_empty, test!(key_empty, include_str!("invalid/key-empty.toml"));
include_str!("invalid/table-array-malformed-empty.toml")); test!(key_hash, include_str!("invalid/key-hash.toml"));
test!(table_empty, test!(key_newline, include_str!("invalid/key-newline.toml"));
include_str!("invalid/table-empty.toml")); test!(
test!(table_nested_brackets_close, key_open_bracket,
include_str!("invalid/table-nested-brackets-close.toml")); include_str!("invalid/key-open-bracket.toml")
test!(table_nested_brackets_open, );
include_str!("invalid/table-nested-brackets-open.toml")); test!(
test!(table_whitespace, key_single_open_bracket,
include_str!("invalid/table-whitespace.toml")); include_str!("invalid/key-single-open-bracket.toml")
test!(table_with_pound, );
include_str!("invalid/table-with-pound.toml")); test!(key_space, include_str!("invalid/key-space.toml"));
test!(text_after_array_entries, test!(
include_str!("invalid/text-after-array-entries.toml")); key_start_bracket,
test!(text_after_integer, include_str!("invalid/key-start-bracket.toml")
include_str!("invalid/text-after-integer.toml")); );
test!(text_after_string, test!(key_two_equals, include_str!("invalid/key-two-equals.toml"));
include_str!("invalid/text-after-string.toml")); test!(
test!(text_after_table, string_bad_byte_escape,
include_str!("invalid/text-after-table.toml")); include_str!("invalid/string-bad-byte-escape.toml")
test!(text_before_array_separator, );
include_str!("invalid/text-before-array-separator.toml")); test!(
test!(text_in_array, string_bad_escape,
include_str!("invalid/text-in-array.toml")); include_str!("invalid/string-bad-escape.toml")
);
test!(
string_bad_line_ending_escape,
include_str!("invalid/string-bad-line-ending-escape.toml")
);
test!(
string_byte_escapes,
include_str!("invalid/string-byte-escapes.toml")
);
test!(
string_no_close,
include_str!("invalid/string-no-close.toml")
);
test!(
table_array_implicit,
include_str!("invalid/table-array-implicit.toml")
);
test!(
table_array_malformed_bracket,
include_str!("invalid/table-array-malformed-bracket.toml")
);
test!(
table_array_malformed_empty,
include_str!("invalid/table-array-malformed-empty.toml")
);
test!(table_empty, include_str!("invalid/table-empty.toml"));
test!(
table_nested_brackets_close,
include_str!("invalid/table-nested-brackets-close.toml")
);
test!(
table_nested_brackets_open,
include_str!("invalid/table-nested-brackets-open.toml")
);
test!(
table_whitespace,
include_str!("invalid/table-whitespace.toml")
);
test!(
table_with_pound,
include_str!("invalid/table-with-pound.toml")
);
test!(
text_after_array_entries,
include_str!("invalid/text-after-array-entries.toml")
);
test!(
text_after_integer,
include_str!("invalid/text-after-integer.toml")
);
test!(
text_after_string,
include_str!("invalid/text-after-string.toml")
);
test!(
text_after_table,
include_str!("invalid/text-after-table.toml")
);
test!(
text_before_array_separator,
include_str!("invalid/text-before-array-separator.toml")
);
test!(text_in_array, include_str!("invalid/text-in-array.toml"));

View file

@ -7,6 +7,8 @@ use std::f64;
macro_rules! table { macro_rules! table {
($($key:expr => $value:expr,)*) => {{ ($($key:expr => $value:expr,)*) => {{
// https://github.com/rust-lang/rust/issues/60643
#[allow(unused_mut)]
let mut table = toml::value::Table::new(); let mut table = toml::value::Table::new();
$( $(
table.insert($key.to_string(), $value.into()); table.insert($key.to_string(), $value.into());
@ -17,6 +19,8 @@ macro_rules! table {
macro_rules! array { macro_rules! array {
($($element:expr,)*) => {{ ($($element:expr,)*) => {{
// https://github.com/rust-lang/rust/issues/60643
#[allow(unused_mut)]
let mut array = toml::value::Array::new(); let mut array = toml::value::Array::new();
$( $(
array.push($element.into()); array.push($element.into());

View file

@ -3,7 +3,7 @@ extern crate toml;
use toml::Value; use toml::Value;
macro_rules! bad { macro_rules! bad {
($s:expr, $msg:expr) => ({ ($s:expr, $msg:expr) => {{
match $s.parse::<Value>() { match $s.parse::<Value>() {
Ok(s) => panic!("successfully parsed as {}", s), Ok(s) => panic!("successfully parsed as {}", s),
Err(e) => { Err(e) => {
@ -11,29 +11,31 @@ macro_rules! bad {
assert!(e.contains($msg), "error: {}", e); assert!(e.contains($msg), "error: {}", e);
} }
} }
}) }};
} }
#[test] #[test]
fn crlf() { fn crlf() {
"\ "\
[project]\r\n\ [project]\r\n\
\r\n\ \r\n\
name = \"splay\"\r\n\ name = \"splay\"\r\n\
version = \"0.1.0\"\r\n\ version = \"0.1.0\"\r\n\
authors = [\"alex@crichton.co\"]\r\n\ authors = [\"alex@crichton.co\"]\r\n\
\r\n\ \r\n\
[[lib]]\r\n\ [[lib]]\r\n\
\r\n\ \r\n\
path = \"lib.rs\"\r\n\ path = \"lib.rs\"\r\n\
name = \"splay\"\r\n\ name = \"splay\"\r\n\
description = \"\"\"\ description = \"\"\"\
A Rust implementation of a TAR file reader and writer. This library does not\r\n\ A Rust implementation of a TAR file reader and writer. This library does not\r\n\
currently handle compression, but it is abstract over all I/O readers and\r\n\ currently handle compression, but it is abstract over all I/O readers and\r\n\
writers. Additionally, great lengths are taken to ensure that the entire\r\n\ writers. Additionally, great lengths are taken to ensure that the entire\r\n\
contents are never required to be entirely resident in memory all at once.\r\n\ contents are never required to be entirely resident in memory all at once.\r\n\
\"\"\"\ \"\"\"\
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
} }
#[test] #[test]
@ -71,7 +73,9 @@ trimmed in raw strings.
All other whitespace All other whitespace
is preserved. is preserved.
''' '''
"#.parse::<Value>().unwrap(); "#
.parse::<Value>()
.unwrap();
assert_eq!(table["bar"].as_str(), Some("\0")); assert_eq!(table["bar"].as_str(), Some("\0"));
assert_eq!(table["key1"].as_str(), Some("One\nTwo")); assert_eq!(table["key1"].as_str(), Some("One\nTwo"));
assert_eq!(table["key2"].as_str(), Some("One\nTwo")); assert_eq!(table["key2"].as_str(), Some("One\nTwo"));
@ -82,16 +86,32 @@ is preserved.
assert_eq!(table["key5"].as_str(), Some(msg)); assert_eq!(table["key5"].as_str(), Some(msg));
assert_eq!(table["key6"].as_str(), Some(msg)); assert_eq!(table["key6"].as_str(), Some(msg));
assert_eq!(table["winpath"].as_str(), Some(r"C:\Users\nodejs\templates")); assert_eq!(
assert_eq!(table["winpath2"].as_str(), Some(r"\\ServerX\admin$\system32\")); table["winpath"].as_str(),
assert_eq!(table["quoted"].as_str(), Some(r#"Tom "Dubs" Preston-Werner"#)); Some(r"C:\Users\nodejs\templates")
);
assert_eq!(
table["winpath2"].as_str(),
Some(r"\\ServerX\admin$\system32\")
);
assert_eq!(
table["quoted"].as_str(),
Some(r#"Tom "Dubs" Preston-Werner"#)
);
assert_eq!(table["regex"].as_str(), Some(r"<\i\c*\s*>")); assert_eq!(table["regex"].as_str(), Some(r"<\i\c*\s*>"));
assert_eq!(table["regex2"].as_str(), Some(r"I [dw]on't need \d{2} apples")); assert_eq!(
assert_eq!(table["lines"].as_str(), table["regex2"].as_str(),
Some("The first newline is\n\ Some(r"I [dw]on't need \d{2} apples")
trimmed in raw strings.\n\ );
All other whitespace\n\ assert_eq!(
is preserved.\n")); table["lines"].as_str(),
Some(
"The first newline is\n\
trimmed in raw strings.\n\
All other whitespace\n\
is preserved.\n"
)
);
} }
#[test] #[test]
@ -106,7 +126,9 @@ fn tables_in_arrays() {
# #
[foo.bar] [foo.bar]
#... #...
"#.parse::<Value>().unwrap(); "#
.parse::<Value>()
.unwrap();
table["foo"][0]["bar"].as_table().unwrap(); table["foo"][0]["bar"].as_table().unwrap();
table["foo"][1]["bar"].as_table().unwrap(); table["foo"][1]["bar"].as_table().unwrap();
} }
@ -114,7 +136,9 @@ fn tables_in_arrays() {
#[test] #[test]
fn empty_table() { fn empty_table() {
let table = r#" let table = r#"
[foo]"#.parse::<Value>().unwrap(); [foo]"#
.parse::<Value>()
.unwrap();
table["foo"].as_table().unwrap(); table["foo"].as_table().unwrap();
} }
@ -139,14 +163,28 @@ name = "banana"
[[fruit.variety]] [[fruit.variety]]
name = "plantain" name = "plantain"
"#.parse::<Value>().unwrap(); "#
.parse::<Value>()
.unwrap();
assert_eq!(table["fruit"][0]["name"].as_str(), Some("apple")); assert_eq!(table["fruit"][0]["name"].as_str(), Some("apple"));
assert_eq!(table["fruit"][0]["physical"]["color"].as_str(), Some("red")); assert_eq!(table["fruit"][0]["physical"]["color"].as_str(), Some("red"));
assert_eq!(table["fruit"][0]["physical"]["shape"].as_str(), Some("round")); assert_eq!(
assert_eq!(table["fruit"][0]["variety"][0]["name"].as_str(), Some("red delicious")); table["fruit"][0]["physical"]["shape"].as_str(),
assert_eq!(table["fruit"][0]["variety"][1]["name"].as_str(), Some("granny smith")); Some("round")
);
assert_eq!(
table["fruit"][0]["variety"][0]["name"].as_str(),
Some("red delicious")
);
assert_eq!(
table["fruit"][0]["variety"][1]["name"].as_str(),
Some("granny smith")
);
assert_eq!(table["fruit"][1]["name"].as_str(), Some("banana")); assert_eq!(table["fruit"][1]["name"].as_str(), Some("banana"));
assert_eq!(table["fruit"][1]["variety"][0]["name"].as_str(), Some("plantain")); assert_eq!(
table["fruit"][1]["variety"][0]["name"].as_str(),
Some("plantain")
);
} }
#[test] #[test]
@ -177,7 +215,9 @@ fn literal_eats_crlf() {
let table = " let table = "
foo = \"\"\"\\\r\n\"\"\" foo = \"\"\"\\\r\n\"\"\"
bar = \"\"\"\\\r\n \r\n \r\n a\"\"\" bar = \"\"\"\\\r\n \r\n \r\n a\"\"\"
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
assert_eq!(table["foo"].as_str(), Some("")); assert_eq!(table["foo"].as_str(), Some(""));
assert_eq!(table["bar"].as_str(), Some("a")); assert_eq!(table["bar"].as_str(), Some("a"));
} }
@ -215,12 +255,12 @@ fn bad_floats() {
#[test] #[test]
fn floats() { fn floats() {
macro_rules! t { macro_rules! t {
($actual:expr, $expected:expr) => ({ ($actual:expr, $expected:expr) => {{
let f = format!("foo = {}", $actual); let f = format!("foo = {}", $actual);
println!("{}", f); println!("{}", f);
let a = f.parse::<Value>().unwrap(); let a = f.parse::<Value>().unwrap();
assert_eq!(a["foo"].as_float().unwrap(), $expected); assert_eq!(a["foo"].as_float().unwrap(), $expected);
}) }};
} }
t!("1.0", 1.0); t!("1.0", 1.0);
@ -252,7 +292,9 @@ fn bare_key_names() {
\"\\\"\" = 3 \"\\\"\" = 3
\"character encoding\" = \"value\" \"character encoding\" = \"value\"
'ʎǝʞ' = \"value\" 'ʎǝʞ' = \"value\"
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
&a["foo"]; &a["foo"];
&a["-"]; &a["-"];
&a["_"]; &a["_"];
@ -310,7 +352,9 @@ fn table_names() {
[\"\\\"\"] [\"\\\"\"]
['a.a'] ['a.a']
['\"\"'] ['\"\"']
".parse::<Value>().unwrap(); "
.parse::<Value>()
.unwrap();
println!("{:?}", a); println!("{:?}", a);
&a["a"]["b"]; &a["a"]["b"];
&a["f f"]; &a["f f"];
@ -344,11 +388,11 @@ fn inline_tables() {
#[test] #[test]
fn number_underscores() { fn number_underscores() {
macro_rules! t { macro_rules! t {
($actual:expr, $expected:expr) => ({ ($actual:expr, $expected:expr) => {{
let f = format!("foo = {}", $actual); let f = format!("foo = {}", $actual);
let table = f.parse::<Value>().unwrap(); let table = f.parse::<Value>().unwrap();
assert_eq!(table["foo"].as_integer().unwrap(), $expected); assert_eq!(table["foo"].as_integer().unwrap(), $expected);
}) }};
} }
t!("1_0", 10); t!("1_0", 10);
@ -381,11 +425,12 @@ fn bad_strings() {
#[test] #[test]
fn empty_string() { fn empty_string() {
assert_eq!("foo = \"\"".parse::<Value>() assert_eq!(
.unwrap()["foo"] "foo = \"\"".parse::<Value>().unwrap()["foo"]
.as_str() .as_str()
.unwrap(), .unwrap(),
""); ""
);
} }
#[test] #[test]
@ -404,67 +449,94 @@ fn booleans() {
#[test] #[test]
fn bad_nesting() { fn bad_nesting() {
bad!(" bad!(
"
a = [2] a = [2]
[[a]] [[a]]
b = 5 b = 5
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
a = 1 a = 1
[a.b] [a.b]
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
a = [] a = []
[a.b] [a.b]
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
a = [] a = []
[[a.b]] [[a.b]]
", "duplicate key: `a`"); ",
bad!(" "duplicate key: `a`"
);
bad!(
"
[a] [a]
b = { c = 2, d = {} } b = { c = 2, d = {} }
[a.b] [a.b]
c = 2 c = 2
", "duplicate key: `b`"); ",
"duplicate key: `b`"
);
} }
#[test] #[test]
fn bad_table_redefine() { fn bad_table_redefine() {
bad!(" bad!(
"
[a] [a]
foo=\"bar\" foo=\"bar\"
[a.b] [a.b]
foo=\"bar\" foo=\"bar\"
[a] [a]
", "redefinition of table `a`"); ",
bad!(" "redefinition of table `a`"
);
bad!(
"
[a] [a]
foo=\"bar\" foo=\"bar\"
b = { foo = \"bar\" } b = { foo = \"bar\" }
[a] [a]
", "redefinition of table `a`"); ",
bad!(" "redefinition of table `a`"
);
bad!(
"
[a] [a]
b = {} b = {}
[a.b] [a.b]
", "duplicate key: `b`"); ",
"duplicate key: `b`"
);
bad!(" bad!(
"
[a] [a]
b = {} b = {}
[a] [a]
", "redefinition of table `a`"); ",
"redefinition of table `a`"
);
} }
#[test] #[test]
fn datetimes() { fn datetimes() {
macro_rules! t { macro_rules! t {
($actual:expr) => ({ ($actual:expr) => {{
let f = format!("foo = {}", $actual); let f = format!("foo = {}", $actual);
let toml = f.parse::<Value>().expect(&format!("failed: {}", f)); let toml = f.parse::<Value>().expect(&format!("failed: {}", f));
assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual); assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual);
}) }};
} }
t!("2016-09-09T09:09:09Z"); t!("2016-09-09T09:09:09Z");
@ -481,22 +553,37 @@ fn datetimes() {
#[test] #[test]
fn require_newline_after_value() { fn require_newline_after_value() {
bad!("0=0r=false", "invalid number at line 1"); bad!("0=0r=false", "invalid number at line 1");
bad!(r#" bad!(
r#"
0=""o=""m=""r=""00="0"q="""0"""e="""0""" 0=""o=""m=""r=""00="0"q="""0"""e="""0"""
"#, "expected newline"); "#,
bad!(r#" "expected newline"
);
bad!(
r#"
[[0000l0]] [[0000l0]]
0="0"[[0000l0]] 0="0"[[0000l0]]
0="0"[[0000l0]] 0="0"[[0000l0]]
0="0"l="0" 0="0"l="0"
"#, "expected newline"); "#,
bad!(r#" "expected newline"
);
bad!(
r#"
0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z] 0=[0]00=[0,0,0]t=["0","0","0"]s=[1000-00-00T00:00:00Z,2000-00-00T00:00:00Z]
"#, "expected newline"); "#,
bad!(r#" "expected newline"
);
bad!(
r#"
0=0r0=0r=false 0=0r0=0r=false
"#, "invalid number at line 2"); "#,
bad!(r#" "invalid number at line 2"
);
bad!(
r#"
0=0r0=0r=falsefal=false 0=0r0=0r=falsefal=false
"#, "invalid number at line 2"); "#,
"invalid number at line 2"
);
} }

View file

@ -1,5 +1,5 @@
extern crate toml;
extern crate serde; extern crate serde;
extern crate toml;
use serde::ser::Serialize; use serde::ser::Serialize;
@ -16,7 +16,9 @@ fn no_pretty() {
let toml = NO_PRETTY; let toml = NO_PRETTY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::new(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::new(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
@ -58,13 +60,14 @@ fn pretty_std() {
let toml = PRETTY_STD; let toml = PRETTY_STD;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::pretty(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
} }
const PRETTY_INDENT_2: &'static str = "\ const PRETTY_INDENT_2: &'static str = "\
[example] [example]
array = [ array = [
@ -110,7 +113,6 @@ oneline = \"this has no newlines.\"
text = \"\\nthis is the first line\\nthis is the second line\\n\" text = \"\\nthis is the first line\\nthis is the second line\\n\"
"; ";
#[test] #[test]
/// Test pretty indent when gotten the other way /// Test pretty indent when gotten the other way
fn pretty_indent_2_other() { fn pretty_indent_2_other() {
@ -125,7 +127,6 @@ fn pretty_indent_2_other() {
assert_eq!(toml, &result); assert_eq!(toml, &result);
} }
const PRETTY_ARRAY_NO_COMMA: &'static str = "\ const PRETTY_ARRAY_NO_COMMA: &'static str = "\
[example] [example]
array = [ array = [
@ -150,7 +151,6 @@ fn pretty_indent_array_no_comma() {
assert_eq!(toml, &result); assert_eq!(toml, &result);
} }
const PRETTY_NO_STRING: &'static str = "\ const PRETTY_NO_STRING: &'static str = "\
[example] [example]
array = [ array = [
@ -207,7 +207,9 @@ fn pretty_tricky() {
let toml = PRETTY_TRICKY; let toml = PRETTY_TRICKY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::pretty(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
@ -231,7 +233,9 @@ fn pretty_table_array() {
let toml = PRETTY_TABLE_ARRAY; let toml = PRETTY_TABLE_ARRAY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::pretty(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);
@ -255,7 +259,9 @@ fn table_array() {
let toml = TABLE_ARRAY; let toml = TABLE_ARRAY;
let value: toml::Value = toml::from_str(toml).unwrap(); let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128); let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::new(&mut result)).unwrap(); value
.serialize(&mut toml::Serializer::new(&mut result))
.unwrap();
println!("EXPECTED:\n{}", toml); println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result); println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result); assert_eq!(toml, &result);

View file

@ -4,22 +4,24 @@ extern crate toml;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use std::collections::{BTreeMap, HashSet};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use std::collections::{BTreeMap, HashSet};
use toml::Value;
use toml::Value::{Table, Integer, Array, Float};
use toml::map::Map; use toml::map::Map;
use toml::Value;
use toml::Value::{Array, Float, Integer, Table};
macro_rules! t { macro_rules! t {
($e:expr) => (match $e { ($e:expr) => {
Ok(t) => t, match $e {
Err(e) => panic!("{} failed with {}", stringify!($e), e), Ok(t) => t,
}) Err(e) => panic!("{} failed with {}", stringify!($e), e),
}
};
} }
macro_rules! equivalent { macro_rules! equivalent {
($literal:expr, $toml:expr,) => ({ ($literal:expr, $toml:expr,) => {{
let toml = $toml; let toml = $toml;
let literal = $literal; let literal = $literal;
@ -38,17 +40,16 @@ macro_rules! equivalent {
assert_eq!(literal, t!(toml::from_str(&toml.to_string()))); assert_eq!(literal, t!(toml::from_str(&toml.to_string())));
println!("toml, from_str(toml)"); println!("toml, from_str(toml)");
assert_eq!(toml, t!(toml::from_str(&toml.to_string()))); assert_eq!(toml, t!(toml::from_str(&toml.to_string())));
}) }};
} }
macro_rules! error { macro_rules! error {
($ty:ty, $toml:expr, $error:expr) => ({ ($ty:ty, $toml:expr, $error:expr) => {{
println!("attempting parsing"); println!("attempting parsing");
match toml::from_str::<$ty>(&$toml.to_string()) { match toml::from_str::<$ty>(&$toml.to_string()) {
Ok(_) => panic!("successful"), Ok(_) => panic!("successful"),
Err(e) => { Err(e) => {
assert!(e.to_string().contains($error), assert!(e.to_string().contains($error), "bad error: {}", e);
"bad error: {}", e);
} }
} }
@ -56,11 +57,10 @@ macro_rules! error {
match $toml.try_into::<$ty>() { match $toml.try_into::<$ty>() {
Ok(_) => panic!("successful"), Ok(_) => panic!("successful"),
Err(e) => { Err(e) => {
assert!(e.to_string().contains($error), assert!(e.to_string().contains($error), "bad error: {}", e);
"bad error: {}", e);
} }
} }
}) }};
} }
macro_rules! map( ($($k:ident: $v:expr),*) => ({ macro_rules! map( ($($k:ident: $v:expr),*) => ({
@ -72,12 +72,11 @@ macro_rules! map( ($($k:ident: $v:expr),*) => ({
#[test] #[test]
fn smoke() { fn smoke() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: isize } struct Foo {
a: isize,
}
equivalent!( equivalent!(Foo { a: 2 }, Table(map! { a: Integer(2) }),);
Foo { a: 2 },
Table(map! { a: Integer(2) }),
);
} }
#[test] #[test]
@ -109,9 +108,14 @@ fn smoke_hyphen() {
#[test] #[test]
fn nested() { fn nested() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: isize, b: Bar } struct Foo {
a: isize,
b: Bar,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar { a: String } struct Bar {
a: String,
}
equivalent! { equivalent! {
Foo { a: 2, b: Bar { a: "test".to_string() } }, Foo { a: 2, b: Bar { a: "test".to_string() } },
@ -129,14 +133,14 @@ fn application_decode_error() {
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct Range10(usize); struct Range10(usize);
impl<'de> Deserialize<'de> for Range10 { impl<'de> Deserialize<'de> for Range10 {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Range10, D::Error> { fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Range10, D::Error> {
let x: usize = try!(Deserialize::deserialize(d)); let x: usize = Deserialize::deserialize(d)?;
if x > 10 { if x > 10 {
Err(serde::de::Error::custom("more than 10")) Err(serde::de::Error::custom("more than 10"))
} else { } else {
Ok(Range10(x)) Ok(Range10(x))
} }
} }
} }
let d_good = Integer(5); let d_good = Integer(5);
let d_bad1 = Value::String("not an isize".to_string()); let d_bad1 = Value::String("not an isize".to_string());
@ -153,7 +157,9 @@ fn application_decode_error() {
#[test] #[test]
fn array() { fn array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<isize> } struct Foo {
a: Vec<isize>,
}
equivalent! { equivalent! {
Foo { a: vec![1, 2, 3, 4] }, Foo { a: vec![1, 2, 3, 4] },
@ -239,9 +245,13 @@ fn hashmap() {
#[test] #[test]
fn table_array() { fn table_array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<Bar>, } struct Foo {
a: Vec<Bar>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar { a: isize } struct Bar {
a: isize,
}
equivalent! { equivalent! {
Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] }, Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] },
@ -258,7 +268,9 @@ fn table_array() {
fn type_errors() { fn type_errors() {
#[derive(Deserialize)] #[derive(Deserialize)]
#[allow(dead_code)] #[allow(dead_code)]
struct Foo { bar: isize } struct Foo {
bar: isize,
}
error! { error! {
Foo, Foo,
@ -270,7 +282,9 @@ fn type_errors() {
#[derive(Deserialize)] #[derive(Deserialize)]
#[allow(dead_code)] #[allow(dead_code)]
struct Bar { foo: Foo } struct Bar {
foo: Foo,
}
error! { error! {
Bar, Bar,
@ -286,7 +300,9 @@ fn type_errors() {
#[test] #[test]
fn missing_errors() { fn missing_errors() {
#[derive(Serialize, Deserialize, PartialEq, Debug)] #[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Foo { bar: isize } struct Foo {
bar: isize,
}
error! { error! {
Foo, Foo,
@ -298,7 +314,9 @@ fn missing_errors() {
#[test] #[test]
fn parse_enum() { fn parse_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: E } struct Foo {
a: E,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(untagged)] #[serde(untagged)]
enum E { enum E {
@ -330,7 +348,9 @@ fn parse_enum() {
#[test] #[test]
fn parse_enum_string() { fn parse_enum_string() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Sort } struct Foo {
a: Sort,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
@ -343,7 +363,6 @@ fn parse_enum_string() {
Foo { a: Sort::Desc }, Foo { a: Sort::Desc },
Table(map! { a: Value::String("desc".to_string()) }), Table(map! { a: Value::String("desc".to_string()) }),
} }
} }
// #[test] // #[test]
@ -474,7 +493,9 @@ fn parse_enum_string() {
#[test] #[test]
fn empty_arrays() { fn empty_arrays() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<Bar> } struct Foo {
a: Vec<Bar>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar; struct Bar;
@ -487,7 +508,9 @@ fn empty_arrays() {
#[test] #[test]
fn empty_arrays2() { fn empty_arrays2() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Option<Vec<Bar>> } struct Foo {
a: Option<Vec<Bar>>,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar; struct Bar;
@ -496,7 +519,7 @@ fn empty_arrays2() {
Table(map! {}), Table(map! {}),
} }
equivalent!{ equivalent! {
Foo { a: Some(vec![]) }, Foo { a: Some(vec![]) },
Table(map! { a: Array(vec![]) }), Table(map! { a: Array(vec![]) }),
} }
@ -505,7 +528,9 @@ fn empty_arrays2() {
#[test] #[test]
fn extra_keys() { fn extra_keys() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct Foo { a: isize } struct Foo {
a: isize,
}
let toml = Table(map! { a: Integer(2), b: Integer(2) }); let toml = Table(map! { a: Integer(2), b: Integer(2) });
assert!(toml.clone().try_into::<Foo>().is_ok()); assert!(toml.clone().try_into::<Foo>().is_ok());
@ -516,7 +541,7 @@ fn extra_keys() {
fn newtypes() { fn newtypes() {
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct A { struct A {
b: B b: B,
} }
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
@ -531,19 +556,19 @@ fn newtypes() {
#[test] #[test]
fn newtypes2() { fn newtypes2() {
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct A { struct A {
b: B b: B,
} }
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct B(Option<C>); struct B(Option<C>);
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct C { struct C {
x: u32, x: u32,
y: u32, y: u32,
z: u32 z: u32,
} }
equivalent! { equivalent! {
A { b: B(Some(C { x: 0, y: 1, z: 2 })) }, A { b: B(Some(C { x: 0, y: 1, z: 2 })) },
@ -572,7 +597,10 @@ fn table_structs_empty() {
expected.insert("baz".to_string(), CanBeEmpty::default()); expected.insert("baz".to_string(), CanBeEmpty::default());
expected.insert( expected.insert(
"bazv".to_string(), "bazv".to_string(),
CanBeEmpty {a: Some("foo".to_string()), b: None}, CanBeEmpty {
a: Some("foo".to_string()),
b: None,
},
); );
expected.insert("foo".to_string(), CanBeEmpty::default()); expected.insert("foo".to_string(), CanBeEmpty::default());
assert_eq!(value, expected); assert_eq!(value, expected);
@ -583,7 +611,7 @@ fn table_structs_empty() {
fn fixed_size_array() { fn fixed_size_array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Entity { struct Entity {
pos: [i32; 2] pos: [i32; 2],
} }
equivalent! { equivalent! {
@ -644,10 +672,13 @@ fn homogeneous_tuple_struct() {
fn json_interoperability() { fn json_interoperability() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct Foo { struct Foo {
any: toml::Value any: toml::Value,
} }
let _foo: Foo = serde_json::from_str(r#" let _foo: Foo = serde_json::from_str(
r#"
{"any":1} {"any":1}
"#).unwrap(); "#,
)
.unwrap();
} }

View file

@ -3,9 +3,9 @@ extern crate toml;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use toml::Spanned;
use toml::value::Datetime;
use std::collections::HashMap; use std::collections::HashMap;
use toml::value::Datetime;
use toml::Spanned;
/// A set of good datetimes. /// A set of good datetimes.
pub fn good_datetimes() -> Vec<&'static str> { pub fn good_datetimes() -> Vec<&'static str> {
@ -31,7 +31,10 @@ fn test_spanned_field() {
foo: Spanned<T>, foo: Spanned<T>,
} }
fn good<'de, T>(s: &'de str, expected: &str) where T: serde::Deserialize<'de> { fn good<'de, T>(s: &'de str, expected: &str)
where
T: serde::Deserialize<'de>,
{
let foo: Foo<T> = toml::from_str(s).unwrap(); let foo: Foo<T> = toml::from_str(s).unwrap();
assert_eq!(6, foo.foo.start()); assert_eq!(6, foo.foo.start());
@ -46,18 +49,12 @@ fn test_spanned_field() {
// table // table
good::<HashMap<String, u32>>( good::<HashMap<String, u32>>(
"foo = {\"foo\" = 42, \"bar\" = 42}", "foo = {\"foo\" = 42, \"bar\" = 42}",
"{\"foo\" = 42, \"bar\" = 42}" "{\"foo\" = 42, \"bar\" = 42}",
); );
// array // array
good::<Vec<u32>>( good::<Vec<u32>>("foo = [0, 1, 2, 3, 4]", "[0, 1, 2, 3, 4]");
"foo = [0, 1, 2, 3, 4]",
"[0, 1, 2, 3, 4]"
);
// datetime // datetime
good::<String>( good::<String>("foo = \"1997-09-09T09:09:09Z\"", "\"1997-09-09T09:09:09Z\"");
"foo = \"1997-09-09T09:09:09Z\"",
"\"1997-09-09T09:09:09Z\""
);
for expected in good_datetimes() { for expected in good_datetimes() {
let s = format!("foo = {}", expected); let s = format!("foo = {}", expected);

View file

@ -19,7 +19,9 @@ enum Value {
#[test] #[test]
fn always_works() { fn always_works() {
let mut a = A { vals: HashMap::new() }; let mut a = A {
vals: HashMap::new(),
};
a.vals.insert("foo", Value::Int(0)); a.vals.insert("foo", Value::Int(0));
let mut sub = HashMap::new(); let mut sub = HashMap::new();

View file

@ -1,10 +1,10 @@
extern crate toml;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate toml;
use toml::{Value as Toml, to_string_pretty};
use serde::ser::Serialize; use serde::ser::Serialize;
use serde_json::Value as Json; use serde_json::Value as Json;
use toml::{to_string_pretty, Value as Toml};
fn to_json(toml: toml::Value) -> Json { fn to_json(toml: toml::Value) -> Json {
fn doit(s: &str, json: Json) -> Json { fn doit(s: &str, json: Json) -> Json {
@ -17,11 +17,18 @@ fn to_json(toml: toml::Value) -> Json {
match toml { match toml {
Toml::String(s) => doit("string", Json::String(s)), Toml::String(s) => doit("string", Json::String(s)),
Toml::Integer(i) => doit("integer", Json::String(i.to_string())), Toml::Integer(i) => doit("integer", Json::String(i.to_string())),
Toml::Float(f) => doit("float", Json::String({ Toml::Float(f) => doit(
let s = format!("{:.15}", f); "float",
let s = format!("{}", s.trim_end_matches('0')); Json::String({
if s.ends_with('.') {format!("{}0", s)} else {s} let s = format!("{:.15}", f);
})), let s = format!("{}", s.trim_end_matches('0'));
if s.ends_with('.') {
format!("{}0", s)
} else {
s
}
}),
),
Toml::Boolean(b) => doit("bool", Json::String(format!("{}", b))), Toml::Boolean(b) => doit("bool", Json::String(format!("{}", b))),
Toml::Datetime(s) => doit("datetime", Json::String(s.to_string())), Toml::Datetime(s) => doit("datetime", Json::String(s.to_string())),
Toml::Array(arr) => { Toml::Array(arr) => {
@ -30,7 +37,11 @@ fn to_json(toml: toml::Value) -> Json {
_ => false, _ => false,
}; };
let json = Json::Array(arr.into_iter().map(to_json).collect()); let json = Json::Array(arr.into_iter().map(to_json).collect());
if is_table {json} else {doit("array", json)} if is_table {
json
} else {
doit("array", json)
}
} }
Toml::Table(table) => { Toml::Table(table) => {
let mut map = serde_json::Map::new(); let mut map = serde_json::Map::new();
@ -91,10 +102,12 @@ fn run(toml_raw: &str, json_raw: &str) {
// Assert toml == json // Assert toml == json
let toml_json = to_json(toml.clone()); let toml_json = to_json(toml.clone());
assert!(json == toml_json, assert!(
"expected\n{}\ngot\n{}\n", json == toml_json,
serde_json::to_string_pretty(&json).unwrap(), "expected\n{}\ngot\n{}\n",
serde_json::to_string_pretty(&toml_json).unwrap()); serde_json::to_string_pretty(&json).unwrap(),
serde_json::to_string_pretty(&toml_json).unwrap()
);
// Assert round trip // Assert round trip
println!("round trip parse: {}", toml); println!("round trip parse: {}", toml);
@ -108,152 +121,250 @@ macro_rules! test( ($name:ident, $toml:expr, $json:expr) => (
fn $name() { run($toml, $json); } fn $name() { run($toml, $json); }
) ); ) );
test!(array_empty, test!(
include_str!("valid/array-empty.toml"), array_empty,
include_str!("valid/array-empty.json")); include_str!("valid/array-empty.toml"),
test!(array_nospaces, include_str!("valid/array-empty.json")
include_str!("valid/array-nospaces.toml"), );
include_str!("valid/array-nospaces.json")); test!(
test!(arrays_hetergeneous, array_nospaces,
include_str!("valid/arrays-hetergeneous.toml"), include_str!("valid/array-nospaces.toml"),
include_str!("valid/arrays-hetergeneous.json")); include_str!("valid/array-nospaces.json")
test!(arrays, );
include_str!("valid/arrays.toml"), test!(
include_str!("valid/arrays.json")); arrays_hetergeneous,
test!(arrays_nested, include_str!("valid/arrays-hetergeneous.toml"),
include_str!("valid/arrays-nested.toml"), include_str!("valid/arrays-hetergeneous.json")
include_str!("valid/arrays-nested.json")); );
test!(empty, test!(
include_str!("valid/empty.toml"), arrays,
include_str!("valid/empty.json")); include_str!("valid/arrays.toml"),
test!(bool, include_str!("valid/arrays.json")
include_str!("valid/bool.toml"), );
include_str!("valid/bool.json")); test!(
test!(comments_everywhere, arrays_nested,
include_str!("valid/comments-everywhere.toml"), include_str!("valid/arrays-nested.toml"),
include_str!("valid/comments-everywhere.json")); include_str!("valid/arrays-nested.json")
test!(datetime, );
include_str!("valid/datetime.toml"), test!(
include_str!("valid/datetime.json")); empty,
test!(example, include_str!("valid/empty.toml"),
include_str!("valid/example.toml"), include_str!("valid/empty.json")
include_str!("valid/example.json")); );
test!(float, test!(
include_str!("valid/float.toml"), bool,
include_str!("valid/float.json")); include_str!("valid/bool.toml"),
test!(implicit_and_explicit_after, include_str!("valid/bool.json")
include_str!("valid/implicit-and-explicit-after.toml"), );
include_str!("valid/implicit-and-explicit-after.json")); test!(
test!(implicit_and_explicit_before, comments_everywhere,
include_str!("valid/implicit-and-explicit-before.toml"), include_str!("valid/comments-everywhere.toml"),
include_str!("valid/implicit-and-explicit-before.json")); include_str!("valid/comments-everywhere.json")
test!(implicit_groups, );
include_str!("valid/implicit-groups.toml"), test!(
include_str!("valid/implicit-groups.json")); datetime,
test!(integer, include_str!("valid/datetime.toml"),
include_str!("valid/integer.toml"), include_str!("valid/datetime.json")
include_str!("valid/integer.json")); );
test!(key_equals_nospace, test!(
include_str!("valid/key-equals-nospace.toml"), example,
include_str!("valid/key-equals-nospace.json")); include_str!("valid/example.toml"),
test!(key_space, include_str!("valid/example.json")
include_str!("valid/key-space.toml"), );
include_str!("valid/key-space.json")); test!(
test!(key_special_chars, float,
include_str!("valid/key-special-chars.toml"), include_str!("valid/float.toml"),
include_str!("valid/key-special-chars.json")); include_str!("valid/float.json")
test!(key_with_pound, );
include_str!("valid/key-with-pound.toml"), test!(
include_str!("valid/key-with-pound.json")); implicit_and_explicit_after,
test!(long_float, include_str!("valid/implicit-and-explicit-after.toml"),
include_str!("valid/long-float.toml"), include_str!("valid/implicit-and-explicit-after.json")
include_str!("valid/long-float.json")); );
test!(long_integer, test!(
include_str!("valid/long-integer.toml"), implicit_and_explicit_before,
include_str!("valid/long-integer.json")); include_str!("valid/implicit-and-explicit-before.toml"),
test!(multiline_string, include_str!("valid/implicit-and-explicit-before.json")
include_str!("valid/multiline-string.toml"), );
include_str!("valid/multiline-string.json")); test!(
test!(raw_multiline_string, implicit_groups,
include_str!("valid/raw-multiline-string.toml"), include_str!("valid/implicit-groups.toml"),
include_str!("valid/raw-multiline-string.json")); include_str!("valid/implicit-groups.json")
test!(raw_string, );
include_str!("valid/raw-string.toml"), test!(
include_str!("valid/raw-string.json")); integer,
test!(string_empty, include_str!("valid/integer.toml"),
include_str!("valid/string-empty.toml"), include_str!("valid/integer.json")
include_str!("valid/string-empty.json")); );
test!(string_escapes, test!(
include_str!("valid/string-escapes.toml"), key_equals_nospace,
include_str!("valid/string-escapes.json")); include_str!("valid/key-equals-nospace.toml"),
test!(string_simple, include_str!("valid/key-equals-nospace.json")
include_str!("valid/string-simple.toml"), );
include_str!("valid/string-simple.json")); test!(
test!(string_with_pound, key_space,
include_str!("valid/string-with-pound.toml"), include_str!("valid/key-space.toml"),
include_str!("valid/string-with-pound.json")); include_str!("valid/key-space.json")
test!(table_array_implicit, );
include_str!("valid/table-array-implicit.toml"), test!(
include_str!("valid/table-array-implicit.json")); key_special_chars,
test!(table_array_many, include_str!("valid/key-special-chars.toml"),
include_str!("valid/table-array-many.toml"), include_str!("valid/key-special-chars.json")
include_str!("valid/table-array-many.json")); );
test!(table_array_nest, test!(
include_str!("valid/table-array-nest.toml"), key_with_pound,
include_str!("valid/table-array-nest.json")); include_str!("valid/key-with-pound.toml"),
test!(table_array_one, include_str!("valid/key-with-pound.json")
include_str!("valid/table-array-one.toml"), );
include_str!("valid/table-array-one.json")); test!(
test!(table_empty, long_float,
include_str!("valid/table-empty.toml"), include_str!("valid/long-float.toml"),
include_str!("valid/table-empty.json")); include_str!("valid/long-float.json")
test!(table_sub_empty, );
include_str!("valid/table-sub-empty.toml"), test!(
include_str!("valid/table-sub-empty.json")); long_integer,
test!(table_multi_empty, include_str!("valid/long-integer.toml"),
include_str!("valid/table-multi-empty.toml"), include_str!("valid/long-integer.json")
include_str!("valid/table-multi-empty.json")); );
test!(table_whitespace, test!(
include_str!("valid/table-whitespace.toml"), multiline_string,
include_str!("valid/table-whitespace.json")); include_str!("valid/multiline-string.toml"),
test!(table_with_pound, include_str!("valid/multiline-string.json")
include_str!("valid/table-with-pound.toml"), );
include_str!("valid/table-with-pound.json")); test!(
test!(unicode_escape, raw_multiline_string,
include_str!("valid/unicode-escape.toml"), include_str!("valid/raw-multiline-string.toml"),
include_str!("valid/unicode-escape.json")); include_str!("valid/raw-multiline-string.json")
test!(unicode_literal, );
include_str!("valid/unicode-literal.toml"), test!(
include_str!("valid/unicode-literal.json")); raw_string,
test!(hard_example, include_str!("valid/raw-string.toml"),
include_str!("valid/hard_example.toml"), include_str!("valid/raw-string.json")
include_str!("valid/hard_example.json")); );
test!(example2, test!(
include_str!("valid/example2.toml"), string_empty,
include_str!("valid/example2.json")); include_str!("valid/string-empty.toml"),
test!(example3, include_str!("valid/string-empty.json")
include_str!("valid/example-v0.3.0.toml"), );
include_str!("valid/example-v0.3.0.json")); test!(
test!(example4, string_escapes,
include_str!("valid/example-v0.4.0.toml"), include_str!("valid/string-escapes.toml"),
include_str!("valid/example-v0.4.0.json")); include_str!("valid/string-escapes.json")
test!(example_bom, );
include_str!("valid/example-bom.toml"), test!(
include_str!("valid/example.json")); string_simple,
include_str!("valid/string-simple.toml"),
include_str!("valid/string-simple.json")
);
test!(
string_with_pound,
include_str!("valid/string-with-pound.toml"),
include_str!("valid/string-with-pound.json")
);
test!(
table_array_implicit,
include_str!("valid/table-array-implicit.toml"),
include_str!("valid/table-array-implicit.json")
);
test!(
table_array_many,
include_str!("valid/table-array-many.toml"),
include_str!("valid/table-array-many.json")
);
test!(
table_array_nest,
include_str!("valid/table-array-nest.toml"),
include_str!("valid/table-array-nest.json")
);
test!(
table_array_one,
include_str!("valid/table-array-one.toml"),
include_str!("valid/table-array-one.json")
);
test!(
table_empty,
include_str!("valid/table-empty.toml"),
include_str!("valid/table-empty.json")
);
test!(
table_sub_empty,
include_str!("valid/table-sub-empty.toml"),
include_str!("valid/table-sub-empty.json")
);
test!(
table_multi_empty,
include_str!("valid/table-multi-empty.toml"),
include_str!("valid/table-multi-empty.json")
);
test!(
table_whitespace,
include_str!("valid/table-whitespace.toml"),
include_str!("valid/table-whitespace.json")
);
test!(
table_with_pound,
include_str!("valid/table-with-pound.toml"),
include_str!("valid/table-with-pound.json")
);
test!(
unicode_escape,
include_str!("valid/unicode-escape.toml"),
include_str!("valid/unicode-escape.json")
);
test!(
unicode_literal,
include_str!("valid/unicode-literal.toml"),
include_str!("valid/unicode-literal.json")
);
test!(
hard_example,
include_str!("valid/hard_example.toml"),
include_str!("valid/hard_example.json")
);
test!(
example2,
include_str!("valid/example2.toml"),
include_str!("valid/example2.json")
);
test!(
example3,
include_str!("valid/example-v0.3.0.toml"),
include_str!("valid/example-v0.3.0.json")
);
test!(
example4,
include_str!("valid/example-v0.4.0.toml"),
include_str!("valid/example-v0.4.0.json")
);
test!(
example_bom,
include_str!("valid/example-bom.toml"),
include_str!("valid/example.json")
);
test!(datetime_truncate, test!(
include_str!("valid/datetime-truncate.toml"), datetime_truncate,
include_str!("valid/datetime-truncate.json")); include_str!("valid/datetime-truncate.toml"),
test!(key_quote_newline, include_str!("valid/datetime-truncate.json")
include_str!("valid/key-quote-newline.toml"), );
include_str!("valid/key-quote-newline.json")); test!(
test!(table_array_nest_no_keys, key_quote_newline,
include_str!("valid/table-array-nest-no-keys.toml"), include_str!("valid/key-quote-newline.toml"),
include_str!("valid/table-array-nest-no-keys.json")); include_str!("valid/key-quote-newline.json")
test!(dotted_keys, );
include_str!("valid/dotted-keys.toml"), test!(
include_str!("valid/dotted-keys.json")); table_array_nest_no_keys,
include_str!("valid/table-array-nest-no-keys.toml"),
include_str!("valid/table-array-nest-no-keys.json")
);
test!(
dotted_keys,
include_str!("valid/dotted-keys.toml"),
include_str!("valid/dotted-keys.json")
);
test!(quote_surrounded_value, test!(
include_str!("valid/quote-surrounded-value.toml"), quote_surrounded_value,
include_str!("valid/quote-surrounded-value.json")); include_str!("valid/quote-surrounded-value.toml"),
include_str!("valid/quote-surrounded-value.json")
);