commit
b44ea161d3
|
@ -9,6 +9,7 @@ before_script:
|
|||
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
|
||||
script:
|
||||
- cargo test
|
||||
- cargo test --manifest-path test-suite/Cargo.toml
|
||||
- rustdoc --test README.md -L target
|
||||
- test "$TRAVIS_RUST_VERSION" != "1.15.0" && cargo doc --no-deps || echo "skipping cargo doc"
|
||||
after_success:
|
||||
|
|
|
@ -166,3 +166,6 @@ pub mod de;
|
|||
#[doc(no_inline)]
|
||||
pub use de::{from_slice, from_str, Deserializer};
|
||||
mod tokens;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod macros;
|
||||
|
|
373
src/macros.rs
Normal file
373
src/macros.rs
Normal file
|
@ -0,0 +1,373 @@
|
|||
pub use serde::de::{Deserialize, IntoDeserializer};
|
||||
|
||||
use value::{Value, Table, Array};
|
||||
|
||||
/// Construct a [`toml::Value`] from TOML syntax.
|
||||
///
|
||||
/// [`toml::Value`]: value/enum.Value.html
|
||||
///
|
||||
/// ```rust
|
||||
/// #[macro_use]
|
||||
/// extern crate toml;
|
||||
///
|
||||
/// fn main() {
|
||||
/// let cargo_toml = toml! {
|
||||
/// [package]
|
||||
/// name = "toml"
|
||||
/// version = "0.4.5"
|
||||
/// authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
///
|
||||
/// [badges]
|
||||
/// travis-ci = { repository = "alexcrichton/toml-rs" }
|
||||
///
|
||||
/// [dependencies]
|
||||
/// serde = "1.0"
|
||||
///
|
||||
/// [dev-dependencies]
|
||||
/// serde_derive = "1.0"
|
||||
/// serde_json = "1.0"
|
||||
/// };
|
||||
///
|
||||
/// println!("{:#?}", cargo_toml);
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! toml {
|
||||
($($toml:tt)+) => {{
|
||||
let table = $crate::value::Table::new();
|
||||
let mut root = $crate::Value::Table(table);
|
||||
toml_internal!(@toplevel root [] $($toml)+);
|
||||
root
|
||||
}};
|
||||
}
|
||||
|
||||
// TT-muncher to parse TOML syntax into a toml::Value.
|
||||
//
|
||||
// @toplevel -- Parse tokens outside of an inline table or inline array. In
|
||||
// this state, `[table headers]` and `[[array headers]]` are
|
||||
// allowed and `key = value` pairs are not separated by commas.
|
||||
//
|
||||
// @topleveldatetime -- Helper to parse a Datetime from string and insert it
|
||||
// into a table, continuing in the @toplevel state.
|
||||
//
|
||||
// @path -- Turn a path segment into a string. Segments that look like idents
|
||||
// are stringified, while quoted segments like `"cfg(windows)"`
|
||||
// are not.
|
||||
//
|
||||
// @value -- Parse the value part of a `key = value` pair, which may be a
|
||||
// primitive or inline table or inline array.
|
||||
//
|
||||
// @table -- Parse the contents of an inline table, returning them as a
|
||||
// toml::Value::Table.
|
||||
//
|
||||
// @tabledatetime -- Helper to parse a Datetime from string and insert it
|
||||
// into a table, continuing in the @table state.
|
||||
//
|
||||
// @array -- Parse the contents of an inline array, returning them as a
|
||||
// toml::Value::Array.
|
||||
//
|
||||
// @arraydatetime -- Helper to parse a Datetime from string and push it into
|
||||
// an array, continuing in the @array state.
|
||||
//
|
||||
// @trailingcomma -- Helper to append a comma to a sequence of tokens if the
|
||||
// sequence is non-empty and does not already end in a trailing
|
||||
// comma.
|
||||
//
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! toml_internal {
|
||||
// Base case, no elements remaining.
|
||||
(@toplevel $root:ident [$($path:tt)*]) => {};
|
||||
|
||||
// Parse negative number `key = -value`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = - $v:tt $($rest:tt)*) => {
|
||||
toml_internal!(@toplevel $root [$($path)*] $($k)-+ = (-$v) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `key = 1979-05-27T00:32:00.999999-07:00`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `key = 1979-05-27T00:32:00-07:00`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local datetime `key = 1979-05-27T00:32:00.999999`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `key = 1979-05-27T07:32:00Z` and local datetime `key = 1979-05-27T07:32:00`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local date `key = 1979-05-27`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $yr:tt - $mo:tt - $day:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $day) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local time `key = 00:32:00.999999`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($hr : $min : $sec . $frac) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local time `key = 07:32:00`.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
|
||||
toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($hr : $min : $sec) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse any other `key = value` including string, inline array, inline
|
||||
// table, number, and boolean.
|
||||
(@toplevel $root:ident [$($path:tt)*] $($k:tt)-+ = $v:tt $($rest:tt)*) => {
|
||||
$crate::macros::insert_toml(
|
||||
&mut $root,
|
||||
&[$($path)* &concat!($("-", toml_internal!(@path $k),)+)[1..]],
|
||||
toml_internal!(@value $v));
|
||||
toml_internal!(@toplevel $root [$($path)*] $($rest)*);
|
||||
};
|
||||
|
||||
// Parse array header `[[bin]]`.
|
||||
(@toplevel $root:ident $oldpath:tt [[$($($path:tt)-+).+]] $($rest:tt)*) => {
|
||||
$crate::macros::push_toml(
|
||||
&mut $root,
|
||||
&[$(&concat!($("-", toml_internal!(@path $path),)+)[1..],)+]);
|
||||
toml_internal!(@toplevel $root [$(&concat!($("-", toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
|
||||
};
|
||||
|
||||
// Parse table header `[patch.crates-io]`.
|
||||
(@toplevel $root:ident $oldpath:tt [$($($path:tt)-+).+] $($rest:tt)*) => {
|
||||
$crate::macros::insert_toml(
|
||||
&mut $root,
|
||||
&[$(&concat!($("-", toml_internal!(@path $path),)+)[1..],)+],
|
||||
$crate::Value::Table($crate::value::Table::new()));
|
||||
toml_internal!(@toplevel $root [$(&concat!($("-", toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
|
||||
};
|
||||
|
||||
// Parse datetime from string and insert into table.
|
||||
(@topleveldatetime $root:ident [$($path:tt)*] $($k:tt)-+ = ($($datetime:tt)+) $($rest:tt)*) => {
|
||||
$crate::macros::insert_toml(
|
||||
&mut $root,
|
||||
&[$($path)* &concat!($("-", toml_internal!(@path $k),)+)[1..]],
|
||||
$crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
|
||||
toml_internal!(@toplevel $root [$($path)*] $($rest)*);
|
||||
};
|
||||
|
||||
// Turn a path segment into a string.
|
||||
(@path $ident:ident) => {
|
||||
stringify!($ident)
|
||||
};
|
||||
|
||||
// For a path segment that is not an ident, expect that it is already a
|
||||
// quoted string, like in `[target."cfg(windows)".dependencies]`.
|
||||
(@path $quoted:tt) => {
|
||||
$quoted
|
||||
};
|
||||
|
||||
// Construct a Value from an inline table.
|
||||
(@value { $($inline:tt)* }) => {{
|
||||
let mut table = $crate::value::Table::new();
|
||||
toml_internal!(@trailingcomma (@table table) $($inline)*);
|
||||
$crate::Value::Table(table)
|
||||
}};
|
||||
|
||||
// Construct a Value from an inline array.
|
||||
(@value [ $($inline:tt)* ]) => {{
|
||||
let mut array = $crate::value::Array::new();
|
||||
toml_internal!(@trailingcomma (@array array) $($inline)*);
|
||||
$crate::Value::Array(array)
|
||||
}};
|
||||
|
||||
// Construct a Value from any other type, probably string or boolean or number.
|
||||
(@value $v:tt) => {{
|
||||
// TODO: Implement this with something like serde_json::to_value instead.
|
||||
let de = $crate::macros::IntoDeserializer::<$crate::de::Error>::into_deserializer($v);
|
||||
<$crate::Value as $crate::macros::Deserialize>::deserialize(de).unwrap()
|
||||
}};
|
||||
|
||||
// Base case of inline table.
|
||||
(@table $root:ident) => {};
|
||||
|
||||
// Parse negative number `key = -value`.
|
||||
(@table $root:ident $($k:tt)-+ = - $v:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@table $root $($k)-+ = (-$v) , $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `key = 1979-05-27T00:32:00.999999-07:00`.
|
||||
(@table $root:ident $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `key = 1979-05-27T00:32:00-07:00`.
|
||||
(@table $root:ident $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local datetime `key = 1979-05-27T00:32:00.999999`.
|
||||
(@table $root:ident $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `key = 1979-05-27T07:32:00Z` and local datetime `key = 1979-05-27T07:32:00`.
|
||||
(@table $root:ident $($k:tt)-+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local date `key = 1979-05-27`.
|
||||
(@table $root:ident $($k:tt)-+ = $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $day) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local time `key = 00:32:00.999999`.
|
||||
(@table $root:ident $($k:tt)-+ = $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($hr : $min : $sec . $frac) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local time `key = 07:32:00`.
|
||||
(@table $root:ident $($k:tt)-+ = $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@tabledatetime $root $($k)-+ = ($hr : $min : $sec) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse any other type, probably string or boolean or number.
|
||||
(@table $root:ident $($k:tt)-+ = $v:tt , $($rest:tt)*) => {
|
||||
$root.insert(
|
||||
concat!($("-", toml_internal!(@path $k),)+)[1..].to_owned(),
|
||||
toml_internal!(@value $v));
|
||||
toml_internal!(@table $root $($rest)*);
|
||||
};
|
||||
|
||||
// Parse a Datetime from string and continue in @table state.
|
||||
(@tabledatetime $root:ident $($k:tt)-+ = ($($datetime:tt)*) $($rest:tt)*) => {
|
||||
$root.insert(
|
||||
concat!($("-", toml_internal!(@path $k),)+)[1..].to_owned(),
|
||||
$crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
|
||||
toml_internal!(@table $root $($rest)*);
|
||||
};
|
||||
|
||||
// Base case of inline array.
|
||||
(@array $root:ident) => {};
|
||||
|
||||
// Parse negative number `-value`.
|
||||
(@array $root:ident - $v:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@array $root (-$v) , $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `1979-05-27T00:32:00.999999-07:00`.
|
||||
(@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `1979-05-27T00:32:00-07:00`.
|
||||
(@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local datetime `1979-05-27T00:32:00.999999`.
|
||||
(@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse offset datetime `1979-05-27T07:32:00Z` and local datetime `1979-05-27T07:32:00`.
|
||||
(@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local date `1979-05-27`.
|
||||
(@array $root:ident $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($yr - $mo - $day) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local time `00:32:00.999999`.
|
||||
(@array $root:ident $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($hr : $min : $sec . $frac) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse local time `07:32:00`.
|
||||
(@array $root:ident $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
|
||||
toml_internal!(@arraydatetime $root ($hr : $min : $sec) $($rest)*);
|
||||
};
|
||||
|
||||
// Parse any other type, probably string or boolean or number.
|
||||
(@array $root:ident $v:tt , $($rest:tt)*) => {
|
||||
$root.push(toml_internal!(@value $v));
|
||||
toml_internal!(@array $root $($rest)*);
|
||||
};
|
||||
|
||||
// Parse a Datetime from string and continue in @array state.
|
||||
(@arraydatetime $root:ident ($($datetime:tt)*) $($rest:tt)*) => {
|
||||
$root.push($crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
|
||||
toml_internal!(@array $root $($rest)*);
|
||||
};
|
||||
|
||||
// No trailing comma required if the tokens are empty.
|
||||
(@trailingcomma ($($args:tt)*)) => {
|
||||
toml_internal!($($args)*);
|
||||
};
|
||||
|
||||
// Tokens end with a trailing comma, do not append another one.
|
||||
(@trailingcomma ($($args:tt)*) ,) => {
|
||||
toml_internal!($($args)* ,);
|
||||
};
|
||||
|
||||
// Tokens end with something other than comma, append a trailing comma.
|
||||
(@trailingcomma ($($args:tt)*) $last:tt) => {
|
||||
toml_internal!($($args)* $last ,);
|
||||
};
|
||||
|
||||
// Not yet at the last token.
|
||||
(@trailingcomma ($($args:tt)*) $first:tt $($rest:tt)+) => {
|
||||
toml_internal!(@trailingcomma ($($args)* $first) $($rest)+);
|
||||
};
|
||||
}
|
||||
|
||||
// Called when parsing a `key = value` pair.
|
||||
// Inserts an entry into the table at the given path.
|
||||
pub fn insert_toml(root: &mut Value, path: &[&str], value: Value) {
|
||||
*traverse(root, path) = value;
|
||||
}
|
||||
|
||||
// Called when parsing an `[[array header]]`.
|
||||
// Pushes an empty table onto the array at the given path.
|
||||
pub fn push_toml(root: &mut Value, path: &[&str]) {
|
||||
let target = traverse(root, path);
|
||||
if !target.is_array() {
|
||||
*target = Value::Array(Array::new());
|
||||
}
|
||||
target.as_array_mut().unwrap().push(Value::Table(Table::new()));
|
||||
}
|
||||
|
||||
fn traverse<'a>(root: &'a mut Value, path: &[&str]) -> &'a mut Value {
|
||||
let mut cur = root;
|
||||
for &key in path {
|
||||
// Lexical lifetimes :D
|
||||
let cur1 = cur;
|
||||
let cur2;
|
||||
|
||||
// From the TOML spec:
|
||||
//
|
||||
// > Each double-bracketed sub-table will belong to the most recently
|
||||
// > defined table element above it.
|
||||
if cur1.is_array() {
|
||||
cur2 = cur1.as_array_mut().unwrap().last_mut().unwrap();
|
||||
} else {
|
||||
cur2 = cur1;
|
||||
};
|
||||
|
||||
// We are about to index into this value, so it better be a table.
|
||||
if !cur2.is_table() {
|
||||
*cur2 = Value::Table(Table::new());
|
||||
}
|
||||
|
||||
if !cur2.as_table().unwrap().contains_key(key) {
|
||||
// Insert an empty table for the next loop iteration to point to.
|
||||
let empty = Value::Table(Table::new());
|
||||
cur2.as_table_mut().unwrap().insert(key.to_owned(), empty);
|
||||
}
|
||||
|
||||
// Step into the current table.
|
||||
cur = cur2.as_table_mut().unwrap().get_mut(key).unwrap();
|
||||
}
|
||||
cur
|
||||
}
|
15
test-suite/Cargo.toml
Normal file
15
test-suite/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "toml_test_suite"
|
||||
version = "0.0.0"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
build = "build.rs"
|
||||
publish = false
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
toml = { path = ".." }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
8
test-suite/build.rs
Normal file
8
test-suite/build.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
extern crate rustc_version;
|
||||
use rustc_version::{version, Version};
|
||||
|
||||
fn main() {
|
||||
if version().unwrap() >= Version::parse("1.20.0").unwrap() {
|
||||
println!(r#"cargo:rustc-cfg=feature="test-quoted-keys-in-macro""#);
|
||||
}
|
||||
}
|
286
test-suite/tests/macros.rs
Normal file
286
test-suite/tests/macros.rs
Normal file
|
@ -0,0 +1,286 @@
|
|||
#![recursion_limit = "128"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate toml;
|
||||
|
||||
macro_rules! table {
|
||||
($($key:expr => $value:expr,)*) => {{
|
||||
let mut table = toml::value::Table::new();
|
||||
$(
|
||||
table.insert($key.to_string(), $value.into());
|
||||
)*
|
||||
toml::Value::Table(table)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! array {
|
||||
($($element:expr,)*) => {{
|
||||
let mut array = toml::value::Array::new();
|
||||
$(
|
||||
array.push($element.into());
|
||||
)*
|
||||
toml::Value::Array(array)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! datetime {
|
||||
($s:tt) => {
|
||||
$s.parse::<toml::value::Datetime>().unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cargo_toml() {
|
||||
// Simple sanity check of:
|
||||
//
|
||||
// - Ordinary tables
|
||||
// - Inline tables
|
||||
// - Inline arrays
|
||||
// - String values
|
||||
// - Table keys containing hyphen
|
||||
// - Table headers containing hyphen
|
||||
let actual = toml! {
|
||||
[package]
|
||||
name = "toml"
|
||||
version = "0.4.5"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "alexcrichton/toml-rs" }
|
||||
|
||||
[dependencies]
|
||||
serde = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
};
|
||||
|
||||
let expected = table! {
|
||||
"package" => table! {
|
||||
"name" => "toml".to_owned(),
|
||||
"version" => "0.4.5".to_owned(),
|
||||
"authors" => array! {
|
||||
"Alex Crichton <alex@alexcrichton.com>".to_owned(),
|
||||
},
|
||||
},
|
||||
"badges" => table! {
|
||||
"travis-ci" => table! {
|
||||
"repository" => "alexcrichton/toml-rs".to_owned(),
|
||||
},
|
||||
},
|
||||
"dependencies" => table! {
|
||||
"serde" => "1.0".to_owned(),
|
||||
},
|
||||
"dev-dependencies" => table! {
|
||||
"serde_derive" => "1.0".to_owned(),
|
||||
"serde_json" => "1.0".to_owned(),
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array() {
|
||||
// Copied from the TOML spec.
|
||||
let actual = toml! {
|
||||
[[fruit]]
|
||||
name = "apple"
|
||||
|
||||
[fruit.physical]
|
||||
color = "red"
|
||||
shape = "round"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "red delicious"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "granny smith"
|
||||
|
||||
[[fruit]]
|
||||
name = "banana"
|
||||
|
||||
[[fruit.variety]]
|
||||
name = "plantain"
|
||||
};
|
||||
|
||||
let expected = table! {
|
||||
"fruit" => array! {
|
||||
table! {
|
||||
"name" => "apple",
|
||||
"physical" => table! {
|
||||
"color" => "red",
|
||||
"shape" => "round",
|
||||
},
|
||||
"variety" => array! {
|
||||
table! {
|
||||
"name" => "red delicious",
|
||||
},
|
||||
table! {
|
||||
"name" => "granny smith",
|
||||
},
|
||||
},
|
||||
},
|
||||
table! {
|
||||
"name" => "banana",
|
||||
"variety" => array! {
|
||||
table! {
|
||||
"name" => "plantain",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_number() {
|
||||
let actual = toml! {
|
||||
positive = 1
|
||||
negative = -1
|
||||
table = { positive = 1, negative = -1 }
|
||||
array = [ 1, -1 ]
|
||||
};
|
||||
|
||||
let expected = table! {
|
||||
"positive" => 1,
|
||||
"negative" => -1,
|
||||
"table" => table! {
|
||||
"positive" => 1,
|
||||
"negative" => -1,
|
||||
},
|
||||
"array" => array! {
|
||||
1,
|
||||
-1,
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_datetime() {
|
||||
let actual = toml! {
|
||||
// Copied from the TOML spec.
|
||||
odt1 = 1979-05-27T07:32:00Z
|
||||
odt2 = 1979-05-27T00:32:00-07:00
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00
|
||||
ldt1 = 1979-05-27T07:32:00
|
||||
ldt2 = 1979-05-27T00:32:00.999999
|
||||
ld1 = 1979-05-27
|
||||
lt1 = 07:32:00
|
||||
lt2 = 00:32:00.999999
|
||||
|
||||
table = {
|
||||
odt1 = 1979-05-27T07:32:00Z,
|
||||
odt2 = 1979-05-27T00:32:00-07:00,
|
||||
odt3 = 1979-05-27T00:32:00.999999-07:00,
|
||||
ldt1 = 1979-05-27T07:32:00,
|
||||
ldt2 = 1979-05-27T00:32:00.999999,
|
||||
ld1 = 1979-05-27,
|
||||
lt1 = 07:32:00,
|
||||
lt2 = 00:32:00.999999,
|
||||
}
|
||||
|
||||
array = [
|
||||
1979-05-27T07:32:00Z,
|
||||
1979-05-27T00:32:00-07:00,
|
||||
1979-05-27T00:32:00.999999-07:00,
|
||||
1979-05-27T07:32:00,
|
||||
1979-05-27T00:32:00.999999,
|
||||
1979-05-27,
|
||||
07:32:00,
|
||||
00:32:00.999999,
|
||||
]
|
||||
};
|
||||
|
||||
let expected = table! {
|
||||
"odt1" => datetime!("1979-05-27T07:32:00Z"),
|
||||
"odt2" => datetime!("1979-05-27T00:32:00-07:00"),
|
||||
"odt3" => datetime!("1979-05-27T00:32:00.999999-07:00"),
|
||||
"ldt1" => datetime!("1979-05-27T07:32:00"),
|
||||
"ldt2" => datetime!("1979-05-27T00:32:00.999999"),
|
||||
"ld1" => datetime!("1979-05-27"),
|
||||
"lt1" => datetime!("07:32:00"),
|
||||
"lt2" => datetime!("00:32:00.999999"),
|
||||
|
||||
"table" => table! {
|
||||
"odt1" => datetime!("1979-05-27T07:32:00Z"),
|
||||
"odt2" => datetime!("1979-05-27T00:32:00-07:00"),
|
||||
"odt3" => datetime!("1979-05-27T00:32:00.999999-07:00"),
|
||||
"ldt1" => datetime!("1979-05-27T07:32:00"),
|
||||
"ldt2" => datetime!("1979-05-27T00:32:00.999999"),
|
||||
"ld1" => datetime!("1979-05-27"),
|
||||
"lt1" => datetime!("07:32:00"),
|
||||
"lt2" => datetime!("00:32:00.999999"),
|
||||
},
|
||||
|
||||
"array" => array! {
|
||||
datetime!("1979-05-27T07:32:00Z"),
|
||||
datetime!("1979-05-27T00:32:00-07:00"),
|
||||
datetime!("1979-05-27T00:32:00.999999-07:00"),
|
||||
datetime!("1979-05-27T07:32:00"),
|
||||
datetime!("1979-05-27T00:32:00.999999"),
|
||||
datetime!("1979-05-27"),
|
||||
datetime!("07:32:00"),
|
||||
datetime!("00:32:00.999999"),
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
// This test requires rustc >= 1.20.
|
||||
#[test]
|
||||
#[cfg(feature = "test-quoted-keys-in-macro")]
|
||||
fn test_quoted_key() {
|
||||
let actual = toml! {
|
||||
"quoted" = true
|
||||
table = { "quoted" = true }
|
||||
|
||||
[target."cfg(windows)".dependencies]
|
||||
winapi = "0.2.8"
|
||||
};
|
||||
|
||||
let expected = table! {
|
||||
"quoted" => true,
|
||||
"table" => table! {
|
||||
"quoted" => true,
|
||||
},
|
||||
"target" => table! {
|
||||
"cfg(windows)" => table! {
|
||||
"dependencies" => table! {
|
||||
"winapi" => "0.2.8",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let actual = toml! {
|
||||
empty_inline_table = {}
|
||||
empty_inline_array = []
|
||||
|
||||
[empty_table]
|
||||
|
||||
[[empty_array]]
|
||||
};
|
||||
|
||||
let expected = table! {
|
||||
"empty_inline_table" => table! {},
|
||||
"empty_inline_array" => array! {},
|
||||
"empty_table" => table! {},
|
||||
"empty_array" => array! {
|
||||
table! {},
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue