Backed out 2 changesets (fd805c59ae56, 270e441c3649) for servo bustage on a CLOSED TREE

Backed out changeset fd805c59ae56
Backed out changeset 270e441c3649

--HG--
extra : histedit_source : 588d462b2f2fd9e6892405637a4c8dcdabde5139
This commit is contained in:
shindli 2018-03-05 18:55:45 +02:00
Родитель 56166f1711
Коммит df4b2c995e
47 изменённых файлов: 5127 добавлений и 7151 удалений

9
Cargo.lock сгенерированный
Просмотреть файл

@ -1680,7 +1680,7 @@ dependencies = [
"style_derive 0.0.1",
"style_traits 0.0.1",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uluru 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1884,11 +1884,8 @@ dependencies = [
[[package]]
name = "toml"
version = "0.4.5"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "traitobject"
@ -2400,7 +2397,7 @@ dependencies = [
"checksum tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "febd81b3e2ef615c6c8077347b33f3f3deec3d708ecd08194c9707b7a1eccfc9"
"checksum tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ab83e7adb5677e42e405fa4ceff75659d93c4d7d7dd22f52fcec59ee9f02af"
"checksum tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "65ae5d255ce739e8537221ed2942e0445f4b3b813daebac1c0050ddaaa3587f9"
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
"checksum uluru 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "519130f0ea964ba540a9d8af1373738c2226f1d465eda07e61db29feb5479db9"

29
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -381,7 +381,7 @@ dependencies = [
"objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"objc_id 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-clipboard 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-clipboard 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -866,7 +866,7 @@ dependencies = [
[[package]]
name = "error-chain"
version = "0.11.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3015,7 +3015,7 @@ dependencies = [
"style_derive 0.0.1",
"style_traits 0.0.1",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"uluru 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3230,11 +3230,8 @@ dependencies = [
[[package]]
name = "toml"
version = "0.4.5"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "traitobject"
@ -3582,11 +3579,11 @@ dependencies = [
[[package]]
name = "x11-clipboard"
version = "0.2.2"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"xcb 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3601,11 +3598,11 @@ dependencies = [
[[package]]
name = "xcb"
version = "0.8.2"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3717,7 +3714,7 @@ dependencies = [
"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f3cc21490995c841d68e00276eba02071ebb269ec24011d5728bd00eabd39e31"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
"checksum euclid 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5069a1354a7eecfdedc97e8e931b1fc455c4d06f5910380a3a049327ca7a0d0a"
"checksum expat-sys 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c470ccb972f2088549b023db8029ed9da9426f5affbf9b62efff7009ab8ed5b1"
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
@ -3893,7 +3890,7 @@ dependencies = [
"checksum threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59f6d3eff89920113dac9db44dde461d71d01e88a5b57b258a0466c32b5d7fe1"
"checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3"
"checksum tinyfiledialogs 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d92a5f7395a9e2895a2361c3121d4a0be0f8dac3be7d91841a5c1c5291b1c6dc"
"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec30350633d6dac9dc1a625786b6cbe9150664be941aac2c35ad7199eab877"
"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
@ -3930,9 +3927,9 @@ dependencies = [
"checksum ws 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04614a58714f3fd4a8b1da4bcae9f031c532d35988c3d39627619248113f8be8"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum x11 2.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5c4ac579b5d324dc4add02312b5d0e3e0218521e2d5779d526ac39ee4bb171"
"checksum x11-clipboard 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2e7374c7699210cca7084ca61d57e09640fc744d1391808cb9ae2fe4ca9bd1df"
"checksum x11-clipboard 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78a35cd979d17b95e0706ab1f3425ecc98565d3873902bd5944b9f5f388327d1"
"checksum x11-dl 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "326c500cdc166fd7c70dd8c8a829cd5c0ce7be5a5d98c25817de2b9bdc67faf8"
"checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de"
"checksum xcb 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "400cebeaedeca931825f11606874080f18aa51370dd3d7e11bc08d5aac8b3142"
"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
"checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"

Просмотреть файл

@ -81,4 +81,4 @@ log = "0.3"
bindgen = { version = "0.33.1", optional = true }
regex = {version = "0.2", optional = true}
walkdir = "1.0"
toml = {version = "0.4.5", optional = true, default-features = false}
toml = {version = "0.2.1", optional = true, default-features = false}

2
third_party/rust/toml/.cargo-checksum.json поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

12
third_party/rust/toml/.travis.yml поставляемый
Просмотреть файл

@ -1,6 +1,5 @@
language: rust
rust:
- 1.15.0
- stable
- beta
- nightly
@ -8,16 +7,19 @@ sudo: false
before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo test
- cargo build --verbose
- cargo build --verbose --no-default-features
- cargo build --verbose --features serde --no-default-features
- cargo test --verbose --features serde
- cargo test --verbose --manifest-path serde-tests/Cargo.toml
- rustdoc --test README.md -L target
- test "$TRAVIS_RUST_VERSION" != "1.15.0" && cargo doc --no-deps || echo "skipping cargo doc"
- cargo doc --no-deps
after_success:
- travis-cargo --only nightly doc-upload
- travis-cargo coveralls --no-sudo
env:
global:
secure: "IDm3Oc3bmIL4/6zixovwkuTkbinqWnKdLfeuKTtHqT4ZbVy+rxTDQBgLGfVngymjciHWkJnvQ8/2nT3/KW4MPNY9Sqt3NfWvO7vj9cXypeNeJ4xFrVK49F7CMM4KTCeSMlDKR1C0TVYGgxFIViLtBw/imivl9fk6J489eKv36sA="
secure: LZMkQQJT5LqLQQ8JyakjvHNqqMPy8lm/SyC+H5cKUVI/xk7xRuti4eKY937N8uSmbff2m9ZYlG6cNwIOfk/nWn8YsqxA8Wg/xugubWzqGuqu+NQ4IZVa7INT2Fiqyk5SPCh8B5fo2x7OBJ24SCkWb2p8bEWAuW8XdZZOdmi3H2I=
notifications:
email:
on_success: never

45
third_party/rust/toml/Cargo.toml поставляемый
Просмотреть файл

@ -1,33 +1,26 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "toml"
version = "0.4.5"
version = "0.2.1"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
description = "A native Rust encoder and decoder of TOML-formatted files and streams. Provides\nimplementations of the standard Serialize/Deserialize traits for TOML data to\nfacilitate deserializing and serializing Rust structures.\n"
homepage = "https://github.com/alexcrichton/toml-rs"
documentation = "https://docs.rs/toml"
license = "MIT/Apache-2.0"
readme = "README.md"
keywords = ["encoding"]
categories = ["config", "encoding", "parser-implementations"]
license = "MIT/Apache-2.0"
repository = "https://github.com/alexcrichton/toml-rs"
[dependencies.serde]
version = "1.0"
[dev-dependencies.serde_derive]
version = "1.0"
homepage = "https://github.com/alexcrichton/toml-rs"
documentation = "http://alexcrichton.com/toml-rs"
description = """
A native Rust encoder and decoder of TOML-formatted files and streams. Provides
implementations of the standard Encodable/Decodable traits for TOML data to
facilitate deserializing and serializing Rust structures.
"""
[dev-dependencies.serde_json]
version = "1.0"
[badges.travis-ci]
repository = "alexcrichton/toml-rs"
[dependencies]
rustc-serialize = { optional = true, version = "0.3.0" }
serde = { optional = true, version = "0.8" }
[features]
default = ["rustc-serialize"]
[dev-dependencies]
rustc-serialize = "0.3"

17
third_party/rust/toml/README.md поставляемый
Просмотреть файл

@ -2,26 +2,21 @@
[![Build Status](https://travis-ci.org/alexcrichton/toml-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/toml-rs)
[![Coverage Status](https://coveralls.io/repos/alexcrichton/toml-rs/badge.svg?branch=master&service=github)](https://coveralls.io/github/alexcrichton/toml-rs?branch=master)
[![Latest Version](https://img.shields.io/crates/v/toml.svg)](https://crates.io/crates/toml)
[![Documentation](https://docs.rs/toml/badge.svg)](https://docs.rs/toml)
A [TOML][toml] decoder and encoder for Rust. This library is currently compliant
with the v0.4.0 version of TOML. This library will also likely continue to stay
up to date with the TOML specification as changes happen.
[Documentation](http://alexcrichton.com/toml-rs)
A [TOML][toml] decoder and encoder for Rust. This library is currently compliant with
the v0.4.0 version of TOML. This library will also likely continue to stay up to
date with the TOML specification as changes happen.
[toml]: https://github.com/toml-lang/toml
```toml
# Cargo.toml
[dependencies]
toml = "0.4"
toml = "0.2"
```
This crate also supports serialization/deserialization through the
[serde](https://serde.rs) crate on crates.io. Currently the older `rustc-serialize`
crate is not supported in the 0.3+ series of the `toml` crate, but 0.2 can be
used for that support.
# License
`toml-rs` is primarily distributed under the terms of both the MIT license and

56
third_party/rust/toml/examples/decode.rs поставляемый
Просмотреть файл

@ -1,56 +0,0 @@
//! An example showing off the usage of `Deserialize` to automatically decode
//! TOML into a Rust `struct`
#![deny(warnings)]
extern crate toml;
extern crate serde;
#[macro_use]
extern crate serde_derive;
/// This is what we're going to decode into. Each field is optional, meaning
/// that it doesn't have to be present in TOML.
#[derive(Debug, Deserialize)]
struct Config {
global_string: Option<String>,
global_integer: Option<u64>,
server: Option<ServerConfig>,
peers: Option<Vec<PeerConfig>>,
}
/// Sub-structs are decoded from tables, so this will decode from the `[server]`
/// table.
///
/// Again, each field is optional, meaning they don't have to be present.
#[derive(Debug, Deserialize)]
struct ServerConfig {
ip: Option<String>,
port: Option<u64>,
}
#[derive(Debug, Deserialize)]
struct PeerConfig {
ip: Option<String>,
port: Option<u64>,
}
fn main() {
let toml_str = r#"
global_string = "test"
global_integer = 5
[server]
ip = "127.0.0.1"
port = 80
[[peers]]
ip = "127.0.0.1"
port = 8080
[[peers]]
ip = "127.0.0.1"
"#;
let decoded: Config = toml::from_str(toml_str).unwrap();
println!("{:#?}", decoded);
}

52
third_party/rust/toml/examples/toml2json.rs поставляемый
Просмотреть файл

@ -1,51 +1,57 @@
#![deny(warnings)]
extern crate toml;
extern crate serde_json;
extern crate rustc_serialize;
use std::fs::File;
use std::env;
use std::io;
use std::io::prelude::*;
use toml::Value as Toml;
use serde_json::Value as Json;
use toml::Value;
use rustc_serialize::json::Json;
fn main() {
let mut args = env::args();
let mut input = String::new();
if args.len() > 1 {
let filename = if args.len() > 1 {
let name = args.nth(1).unwrap();
File::open(&name).and_then(|mut f| {
f.read_to_string(&mut input)
}).unwrap();
name
} else {
io::stdin().read_to_string(&mut input).unwrap();
}
"<stdin>".to_string()
};
match input.parse() {
Ok(toml) => {
let json = convert(toml);
println!("{}", serde_json::to_string_pretty(&json).unwrap());
let mut parser = toml::Parser::new(&input);
let toml = match parser.parse() {
Some(toml) => toml,
None => {
for err in &parser.errors {
let (loline, locol) = parser.to_linecol(err.lo);
let (hiline, hicol) = parser.to_linecol(err.hi);
println!("{}:{}:{}-{}:{} error: {}",
filename, loline, locol, hiline, hicol, err.desc);
}
return
}
Err(error) => println!("failed to parse TOML: {}", error),
}
};
let json = convert(Value::Table(toml));
println!("{}", json.pretty());
}
fn convert(toml: Toml) -> Json {
fn convert(toml: Value) -> Json {
match toml {
Toml::String(s) => Json::String(s),
Toml::Integer(i) => Json::Number(i.into()),
Toml::Float(f) => {
let n = serde_json::Number::from_f64(f)
.expect("float infinite and nan not allowed");
Json::Number(n)
}
Toml::Boolean(b) => Json::Bool(b),
Toml::Array(arr) => Json::Array(arr.into_iter().map(convert).collect()),
Toml::Table(table) => Json::Object(table.into_iter().map(|(k, v)| {
Value::String(s) => Json::String(s),
Value::Integer(i) => Json::I64(i),
Value::Float(f) => Json::F64(f),
Value::Boolean(b) => Json::Boolean(b),
Value::Array(arr) => Json::Array(arr.into_iter().map(convert).collect()),
Value::Table(table) => Json::Object(table.into_iter().map(|(k, v)| {
(k, convert(v))
}).collect()),
Toml::Datetime(dt) => Json::String(dt.to_string()),
Value::Datetime(dt) => Json::String(dt),
}
}

425
third_party/rust/toml/src/datetime.rs поставляемый
Просмотреть файл

@ -1,425 +0,0 @@
use std::fmt;
use std::str::{self, FromStr};
use std::error;
use serde::{de, ser};
/// A parsed TOML datetime value
///
/// This structure is intended to represent the datetime primitive type that can
/// be encoded into TOML documents. This type is a parsed version that contains
/// all metadata internally.
///
/// Currently this type is intentionally conservative and only supports
/// `to_string` as an accessor. Over time though it's intended that it'll grow
/// more support!
///
/// Note that if you're using `Deserialize` to deserialize a TOML document, you
/// can use this as a placeholder for where you're expecting a datetime to be
/// specified.
///
/// Also note though that while this type implements `Serialize` and
/// `Deserialize` it's only recommended to use this type with the TOML format,
/// otherwise encoded in other formats it may look a little odd.
#[derive(PartialEq, Clone)]
pub struct Datetime {
date: Option<Date>,
time: Option<Time>,
offset: Option<Offset>,
}
/// Error returned from parsing a `Datetime` in the `FromStr` implementation.
#[derive(Debug, Clone)]
pub struct DatetimeParseError {
_private: (),
}
// Currently serde itself doesn't have a datetime type, so we map our `Datetime`
// to a special valid in the serde data model. Namely one with thiese special
// fields/struct names.
//
// In general the TOML encoder/decoder will catch this and not literally emit
// these strings but rather emit datetimes as they're intended.
pub const SERDE_STRUCT_FIELD_NAME: &'static str = "$__toml_private_datetime";
pub const SERDE_STRUCT_NAME: &'static str = "$__toml_private_Datetime";
#[derive(PartialEq, Clone)]
struct Date {
year: u16,
month: u8,
day: u8,
}
#[derive(PartialEq, Clone)]
struct Time {
hour: u8,
minute: u8,
second: u8,
nanosecond: u32,
}
#[derive(PartialEq, Clone)]
enum Offset {
Z,
Custom { hours: i8, minutes: u8 },
}
impl fmt::Debug for Datetime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for Datetime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref date) = self.date {
write!(f, "{}", date)?;
}
if let Some(ref time) = self.time {
if self.date.is_some() {
write!(f, "T")?;
}
write!(f, "{}", time)?;
}
if let Some(ref offset) = self.offset {
write!(f, "{}", offset)?;
}
Ok(())
}
}
impl fmt::Display for Date {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:04}-{:02}-{:02}", self.year, self.month, self.day)
}
}
impl fmt::Display for Time {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:02}:{:02}:{:02}", self.hour, self.minute, self.second)?;
if self.nanosecond != 0 {
let s = format!("{:09}", self.nanosecond);
write!(f, ".{}", s.trim_right_matches('0'))?;
}
Ok(())
}
}
impl fmt::Display for Offset {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Offset::Z => write!(f, "Z"),
Offset::Custom { hours, minutes } => {
write!(f, "{:+03}:{:02}", hours, minutes)
}
}
}
}
impl FromStr for Datetime {
type Err = DatetimeParseError;
fn from_str(date: &str) -> Result<Datetime, DatetimeParseError> {
// Accepted formats:
//
// 0000-00-00T00:00:00.00Z
// 0000-00-00T00:00:00.00
// 0000-00-00
// 00:00:00.00
if date.len() < 3 {
return Err(DatetimeParseError { _private: () })
}
let mut offset_allowed = true;
let mut chars = date.chars();
// First up, parse the full date if we can
let full_date = if chars.clone().nth(2) == Some(':') {
offset_allowed = false;
None
} else {
let y1 = digit(&mut chars)? as u16;
let y2 = digit(&mut chars)? as u16;
let y3 = digit(&mut chars)? as u16;
let y4 = digit(&mut chars)? as u16;
match chars.next() {
Some('-') => {}
_ => return Err(DatetimeParseError { _private: () }),
}
let m1 = digit(&mut chars)?;
let m2 = digit(&mut chars)?;
match chars.next() {
Some('-') => {}
_ => return Err(DatetimeParseError { _private: () }),
}
let d1 = digit(&mut chars)?;
let d2 = digit(&mut chars)?;
let date = Date {
year: y1 * 1000 + y2 * 100 + y3 * 10 + y4,
month: m1 * 10 + m2,
day: d1 * 10 + d2,
};
if date.month < 1 || date.month > 12 {
return Err(DatetimeParseError { _private: () })
}
if date.day < 1 || date.day > 31 {
return Err(DatetimeParseError { _private: () })
}
Some(date)
};
// Next parse the "partial-time" if available
let partial_time = if full_date.is_some() &&
chars.clone().next() == Some('T') {
chars.next();
true
} else {
full_date.is_none()
};
let time = if partial_time {
let h1 = digit(&mut chars)?;
let h2 = digit(&mut chars)?;
match chars.next() {
Some(':') => {}
_ => return Err(DatetimeParseError { _private: () }),
}
let m1 = digit(&mut chars)?;
let m2 = digit(&mut chars)?;
match chars.next() {
Some(':') => {}
_ => return Err(DatetimeParseError { _private: () }),
}
let s1 = digit(&mut chars)?;
let s2 = digit(&mut chars)?;
let mut nanosecond = 0;
if chars.clone().next() == Some('.') {
chars.next();
let whole = chars.as_str();
let mut end = whole.len();
for (i, byte) in whole.bytes().enumerate() {
match byte {
b'0' ... b'9' => {
if i < 9 {
let p = 10_u32.pow(8 - i as u32);
nanosecond += p * (byte - b'0') as u32;
}
}
_ => {
end = i;
break;
}
}
}
if end == 0 {
return Err(DatetimeParseError { _private: () })
}
chars = whole[end..].chars();
}
let time = Time {
hour: h1 * 10 + h2,
minute: m1 * 10 + m2,
second: s1 * 10 + s2,
nanosecond: nanosecond,
};
if time.hour > 24 {
return Err(DatetimeParseError { _private: () })
}
if time.minute > 59 {
return Err(DatetimeParseError { _private: () })
}
if time.second > 59 {
return Err(DatetimeParseError { _private: () })
}
if time.nanosecond > 999_999_999 {
return Err(DatetimeParseError { _private: () })
}
Some(time)
} else {
offset_allowed = false;
None
};
// And finally, parse the offset
let offset = if offset_allowed {
let next = chars.clone().next();
if next == Some('Z') {
chars.next();
Some(Offset::Z)
} else if next.is_none() {
None
} else {
let sign = match next {
Some('+') => 1,
Some('-') => -1,
_ => return Err(DatetimeParseError { _private: () }),
};
chars.next();
let h1 = digit(&mut chars)? as i8;
let h2 = digit(&mut chars)? as i8;
match chars.next() {
Some(':') => {}
_ => return Err(DatetimeParseError { _private: () }),
}
let m1 = digit(&mut chars)?;
let m2 = digit(&mut chars)?;
Some(Offset::Custom {
hours: sign * (h1 * 10 + h2),
minutes: m1 * 10 + m2,
})
}
} else {
None
};
// Return an error if we didn't hit eof, otherwise return our parsed
// date
if chars.next().is_some() {
return Err(DatetimeParseError { _private: () })
}
Ok(Datetime {
date: full_date,
time: time,
offset: offset,
})
}
}
fn digit(chars: &mut str::Chars) -> Result<u8, DatetimeParseError> {
match chars.next() {
Some(c) if '0' <= c && c <= '9' => Ok(c as u8 - b'0'),
_ => Err(DatetimeParseError { _private: () }),
}
}
impl ser::Serialize for Datetime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ser::Serializer
{
use serde::ser::SerializeStruct;
let mut s = serializer.serialize_struct(SERDE_STRUCT_NAME, 1)?;
s.serialize_field(SERDE_STRUCT_FIELD_NAME, &self.to_string())?;
s.end()
}
}
impl<'de> de::Deserialize<'de> for Datetime {
fn deserialize<D>(deserializer: D) -> Result<Datetime, D::Error>
where D: de::Deserializer<'de>
{
struct DatetimeVisitor;
impl<'de> de::Visitor<'de> for DatetimeVisitor {
type Value = Datetime;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a TOML datetime")
}
fn visit_map<V>(self, mut visitor: V) -> Result<Datetime, V::Error>
where V: de::MapAccess<'de>
{
let value = visitor.next_key::<DatetimeKey>()?;
if value.is_none() {
return Err(de::Error::custom("datetime key not found"))
}
let v: DatetimeFromString = visitor.next_value()?;
Ok(v.value)
}
}
static FIELDS: [&'static str; 1] = [SERDE_STRUCT_FIELD_NAME];
deserializer.deserialize_struct(SERDE_STRUCT_NAME,
&FIELDS,
DatetimeVisitor)
}
}
struct DatetimeKey;
impl<'de> de::Deserialize<'de> for DatetimeKey {
fn deserialize<D>(deserializer: D) -> Result<DatetimeKey, D::Error>
where D: de::Deserializer<'de>
{
struct FieldVisitor;
impl<'de> de::Visitor<'de> for FieldVisitor {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid datetime field")
}
fn visit_str<E>(self, s: &str) -> Result<(), E>
where E: de::Error
{
if s == SERDE_STRUCT_FIELD_NAME {
Ok(())
} else {
Err(de::Error::custom("expected field with custom name"))
}
}
}
deserializer.deserialize_identifier(FieldVisitor)?;
Ok(DatetimeKey)
}
}
pub struct DatetimeFromString {
pub value: Datetime,
}
impl<'de> de::Deserialize<'de> for DatetimeFromString {
fn deserialize<D>(deserializer: D) -> Result<DatetimeFromString, D::Error>
where D: de::Deserializer<'de>
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = DatetimeFromString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string containing a datetime")
}
fn visit_str<E>(self, s: &str) -> Result<DatetimeFromString, E>
where E: de::Error,
{
match s.parse() {
Ok(date) => Ok(DatetimeFromString { value: date }),
Err(e) => Err(de::Error::custom(e)),
}
}
}
deserializer.deserialize_str(Visitor)
}
}
impl fmt::Display for DatetimeParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
"failed to parse datetime".fmt(f)
}
}
impl error::Error for DatetimeParseError {
fn description(&self) -> &str {
"failed to parse datetime"
}
}

1327
third_party/rust/toml/src/de.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

240
third_party/rust/toml/src/decoder/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,240 @@
use std::error;
use std::fmt;
use std::collections::{btree_map, BTreeMap};
use std::iter::Peekable;
use Value;
use self::DecodeErrorKind::*;
#[cfg(feature = "rustc-serialize")] mod rustc_serialize;
#[cfg(feature = "serde")] mod serde;
/// A structure to transform TOML values into Rust values.
///
/// This decoder implements the serialization `Decoder` interface, allowing
/// `Decodable` types to be generated by this decoder. The input is any
/// arbitrary TOML value.
pub struct Decoder {
/// The TOML value left over after decoding. This can be used to inspect
/// whether fields were decoded or not.
pub toml: Option<Value>,
cur_field: Option<String>,
// These aren't used if serde is in use
#[cfg_attr(feature = "serde", allow(dead_code))]
cur_map: Peekable<btree_map::IntoIter<String, Value>>,
#[cfg_attr(feature = "serde", allow(dead_code))]
leftover_map: ::Table,
}
/// Description for errors which can occur while decoding a type.
#[derive(PartialEq, Debug)]
pub struct DecodeError {
/// Field that this error applies to.
pub field: Option<String>,
/// The type of error which occurred while decoding,
pub kind: DecodeErrorKind,
}
/// Enumeration of possible errors which can occur while decoding a structure.
#[derive(PartialEq, Debug)]
pub enum DecodeErrorKind {
/// An error flagged by the application, e.g. value out of range
ApplicationError(String),
/// A field was expected, but none was found.
ExpectedField(/* type */ Option<&'static str>),
/// A field was found, but it was not an expected one.
UnknownField,
/// A field was found, but it had the wrong type.
ExpectedType(/* expected */ &'static str, /* found */ &'static str),
/// The nth map key was expected, but none was found.
ExpectedMapKey(usize),
/// The nth map element was expected, but none was found.
ExpectedMapElement(usize),
/// An enum decoding was requested, but no variants were supplied
NoEnumVariants,
/// The unit type was being decoded, but a non-zero length string was found
NilTooLong,
/// There was an error with the syntactical structure of the TOML.
SyntaxError,
/// A custom error was generated when decoding.
CustomError(String),
/// The end of the TOML input was reached too soon
EndOfStream,
/// Produced by serde ...
InvalidType(&'static str),
}
/// Decodes a TOML value into a decodable type.
///
/// This function will consume the given TOML value and attempt to decode it
/// into the type specified. If decoding fails, `None` will be returned. If a
/// finer-grained error is desired, then it is recommended to use `Decodable`
/// directly.
#[cfg(feature = "rustc-serialize")]
pub fn decode<T: ::rustc_serialize::Decodable>(toml: Value) -> Option<T> {
::rustc_serialize::Decodable::decode(&mut Decoder::new(toml)).ok()
}
/// Decodes a TOML value into a decodable type.
///
/// This function will consume the given TOML value and attempt to decode it
/// into the type specified. If decoding fails, `None` will be returned. If a
/// finer-grained error is desired, then it is recommended to use `Decodable`
/// directly.
#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))]
pub fn decode<T: ::serde::Deserialize>(toml: Value) -> Option<T> {
::serde::Deserialize::deserialize(&mut Decoder::new(toml)).ok()
}
/// Decodes a string into a toml-encoded value.
///
/// This function will parse the given string into a TOML value, and then parse
/// the TOML value into the desired type. If any error occurs, `None` is
/// returned.
///
/// If more fine-grained errors are desired, these steps should be driven
/// manually.
#[cfg(feature = "rustc-serialize")]
pub fn decode_str<T: ::rustc_serialize::Decodable>(s: &str) -> Option<T> {
::Parser::new(s).parse().and_then(|t| decode(Value::Table(t)))
}
/// Decodes a string into a toml-encoded value.
///
/// This function will parse the given string into a TOML value, and then parse
/// the TOML value into the desired type. If any error occurs, `None` is
/// returned.
///
/// If more fine-grained errors are desired, these steps should be driven
/// manually.
#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))]
pub fn decode_str<T: ::serde::Deserialize>(s: &str) -> Option<T> {
::Parser::new(s).parse().and_then(|t| decode(Value::Table(t)))
}
impl Decoder {
/// Creates a new decoder, consuming the TOML value to decode.
///
/// This decoder can be passed to the `Decodable` methods or driven
/// manually.
pub fn new(toml: Value) -> Decoder {
Decoder::new_empty(Some(toml), None)
}
fn sub_decoder(&self, toml: Option<Value>, field: &str) -> Decoder {
let cur_field = if field.is_empty() {
self.cur_field.clone()
} else {
match self.cur_field {
None => Some(field.to_string()),
Some(ref s) => Some(format!("{}.{}", s, field))
}
};
Decoder::new_empty(toml, cur_field)
}
fn new_empty(toml: Option<Value>, cur_field: Option<String>) -> Decoder {
Decoder {
toml: toml,
cur_field: cur_field,
leftover_map: BTreeMap::new(),
cur_map: BTreeMap::new().into_iter().peekable(),
}
}
fn err(&self, kind: DecodeErrorKind) -> DecodeError {
DecodeError {
field: self.cur_field.clone(),
kind: kind,
}
}
fn mismatch(&self, expected: &'static str,
found: &Option<Value>) -> DecodeError{
match *found {
Some(ref val) => self.err(ExpectedType(expected, val.type_str())),
None => self.err(ExpectedField(Some(expected))),
}
}
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(match self.kind {
ApplicationError(ref err) => {
write!(f, "{}", err)
}
ExpectedField(expected_type) => {
match expected_type {
Some("table") => write!(f, "expected a section"),
Some(e) => write!(f, "expected a value of type `{}`", e),
None => write!(f, "expected a value"),
}
}
UnknownField => write!(f, "unknown field"),
ExpectedType(expected, found) => {
fn humanize(s: &str) -> String {
if s == "section" {
"a section".to_string()
} else {
format!("a value of type `{}`", s)
}
}
write!(f, "expected {}, but found {}",
humanize(expected),
humanize(found))
}
ExpectedMapKey(idx) => {
write!(f, "expected at least {} keys", idx + 1)
}
ExpectedMapElement(idx) => {
write!(f, "expected at least {} elements", idx + 1)
}
NoEnumVariants => {
write!(f, "expected an enum variant to decode to")
}
NilTooLong => {
write!(f, "expected 0-length string")
}
SyntaxError => {
write!(f, "syntax error")
}
EndOfStream => {
write!(f, "end of stream")
}
InvalidType(s) => {
write!(f, "invalid type: {}", s)
}
CustomError(ref s) => {
write!(f, "custom error: {}", s)
}
});
match self.field {
Some(ref s) => {
write!(f, " for the key `{}`", s)
}
None => Ok(())
}
}
}
impl error::Error for DecodeError {
fn description(&self) -> &str {
match self.kind {
ApplicationError(ref s) => &**s,
ExpectedField(..) => "expected a field",
UnknownField => "found an unknown field",
ExpectedType(..) => "expected a type",
ExpectedMapKey(..) => "expected a map key",
ExpectedMapElement(..) => "expected a map element",
NoEnumVariants => "no enum variants to decode to",
NilTooLong => "nonzero length string representing nil",
SyntaxError => "syntax error",
EndOfStream => "end of stream",
InvalidType(..) => "invalid type",
CustomError(..) => "custom error",
}
}
}

371
third_party/rust/toml/src/decoder/rustc_serialize.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,371 @@
use rustc_serialize;
use std::mem;
use std::collections::BTreeMap;
use super::{Decoder, DecodeError};
use super::DecodeErrorKind::*;
use Value;
impl rustc_serialize::Decoder for Decoder {
type Error = DecodeError;
fn read_nil(&mut self) -> Result<(), DecodeError> {
match self.toml {
Some(Value::String(ref s)) if s.is_empty() => {}
Some(Value::String(..)) => return Err(self.err(NilTooLong)),
ref found => return Err(self.mismatch("string", found)),
}
self.toml.take();
Ok(())
}
fn read_usize(&mut self) -> Result<usize, DecodeError> {
self.read_i64().map(|i| i as usize)
}
fn read_u64(&mut self) -> Result<u64, DecodeError> {
self.read_i64().map(|i| i as u64)
}
fn read_u32(&mut self) -> Result<u32, DecodeError> {
self.read_i64().map(|i| i as u32)
}
fn read_u16(&mut self) -> Result<u16, DecodeError> {
self.read_i64().map(|i| i as u16)
}
fn read_u8(&mut self) -> Result<u8, DecodeError> {
self.read_i64().map(|i| i as u8)
}
fn read_isize(&mut self) -> Result<isize, DecodeError> {
self.read_i64().map(|i| i as isize)
}
fn read_i64(&mut self) -> Result<i64, DecodeError> {
match self.toml {
Some(Value::Integer(i)) => { self.toml.take(); Ok(i) }
ref found => Err(self.mismatch("integer", found)),
}
}
fn read_i32(&mut self) -> Result<i32, DecodeError> {
self.read_i64().map(|i| i as i32)
}
fn read_i16(&mut self) -> Result<i16, DecodeError> {
self.read_i64().map(|i| i as i16)
}
fn read_i8(&mut self) -> Result<i8, DecodeError> {
self.read_i64().map(|i| i as i8)
}
fn read_bool(&mut self) -> Result<bool, DecodeError> {
match self.toml {
Some(Value::Boolean(b)) => { self.toml.take(); Ok(b) }
ref found => Err(self.mismatch("bool", found)),
}
}
fn read_f64(&mut self) -> Result<f64, DecodeError> {
match self.toml {
Some(Value::Float(f)) => { self.toml.take(); Ok(f) },
ref found => Err(self.mismatch("float", found)),
}
}
fn read_f32(&mut self) -> Result<f32, DecodeError> {
self.read_f64().map(|f| f as f32)
}
fn read_char(&mut self) -> Result<char, DecodeError> {
let ch = match self.toml {
Some(Value::String(ref s)) if s.chars().count() == 1 =>
s.chars().next().unwrap(),
ref found => return Err(self.mismatch("string", found)),
};
self.toml.take();
Ok(ch)
}
fn read_str(&mut self) -> Result<String, DecodeError> {
match self.toml.take() {
Some(Value::String(s)) => Ok(s),
found => {
let err = Err(self.mismatch("string", &found));
self.toml = found;
err
}
}
}
// Compound types:
fn read_enum<T, F>(&mut self, _name: &str, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
f(self)
}
fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F)
-> Result<T, DecodeError>
where F: FnMut(&mut Decoder, usize) -> Result<T, DecodeError>
{
// When decoding enums, this crate takes the strategy of trying to
// decode the current TOML as all of the possible variants, returning
// success on the first one that succeeds.
//
// Note that fidelity of the errors returned here is a little nebulous,
// but we try to return the error that had the relevant field as the
// longest field. This way we hopefully match an error against what was
// most likely being written down without losing too much info.
let mut first_error = None::<DecodeError>;
for i in 0..names.len() {
let mut d = self.sub_decoder(self.toml.clone(), "");
match f(&mut d, i) {
Ok(t) => {
self.toml = d.toml;
return Ok(t)
}
Err(e) => {
if let Some(ref first) = first_error {
let my_len = e.field.as_ref().map(|s| s.len());
let first_len = first.field.as_ref().map(|s| s.len());
if my_len <= first_len {
continue
}
}
first_error = Some(e);
}
}
}
Err(first_error.unwrap_or_else(|| self.err(NoEnumVariants)))
}
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
f(self)
}
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F)
-> Result<T, DecodeError>
where F: FnMut(&mut Decoder, usize) -> Result<T, DecodeError>
{
panic!()
}
fn read_enum_struct_variant_field<T, F>(&mut self,
_f_name: &str,
_f_idx: usize,
_f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
panic!()
}
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
match self.toml {
Some(Value::Table(..)) => {
let ret = try!(f(self));
match self.toml {
Some(Value::Table(ref t)) if t.is_empty() => {}
_ => return Ok(ret)
}
self.toml.take();
Ok(ret)
}
ref found => Err(self.mismatch("table", found)),
}
}
fn read_struct_field<T, F>(&mut self, f_name: &str, _f_idx: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
let field = f_name.to_string();
let toml = match self.toml {
Some(Value::Table(ref mut table)) => {
table.remove(&field)
.or_else(|| table.remove(&f_name.replace("_", "-")))
},
ref found => return Err(self.mismatch("table", found)),
};
let mut d = self.sub_decoder(toml, f_name);
let ret = try!(f(&mut d));
if let Some(value) = d.toml {
if let Some(Value::Table(ref mut table)) = self.toml {
table.insert(field, value);
}
}
Ok(ret)
}
fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
self.read_seq(move |d, len| {
assert!(len == tuple_len,
"expected tuple of length `{}`, found tuple \
of length `{}`", tuple_len, len);
f(d)
})
}
fn read_tuple_arg<T, F>(&mut self, a_idx: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
self.read_seq_elt(a_idx, f)
}
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
panic!()
}
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
panic!()
}
// Specialized types:
fn read_option<T, F>(&mut self, mut f: F)
-> Result<T, DecodeError>
where F: FnMut(&mut Decoder, bool) -> Result<T, DecodeError>
{
match self.toml {
Some(..) => f(self, true),
None => f(self, false),
}
}
fn read_seq<T, F>(&mut self, f: F) -> Result<T, DecodeError>
where F: FnOnce(&mut Decoder, usize) -> Result<T, DecodeError>
{
let len = match self.toml {
Some(Value::Array(ref arr)) => arr.len(),
None => 0,
ref found => return Err(self.mismatch("array", found)),
};
let ret = try!(f(self, len));
match self.toml {
Some(Value::Array(ref mut arr)) => {
arr.retain(|slot| slot.as_integer() != Some(0));
if !arr.is_empty() { return Ok(ret) }
}
_ => return Ok(ret)
}
self.toml.take();
Ok(ret)
}
fn read_seq_elt<T, F>(&mut self, idx: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
let toml = match self.toml {
Some(Value::Array(ref mut arr)) => {
mem::replace(&mut arr[idx], Value::Integer(0))
}
ref found => return Err(self.mismatch("array", found)),
};
let mut d = self.sub_decoder(Some(toml), "");
let ret = try!(f(&mut d));
if let Some(toml) = d.toml {
if let Some(Value::Array(ref mut arr)) = self.toml {
arr[idx] = toml;
}
}
Ok(ret)
}
fn read_map<T, F>(&mut self, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder, usize) -> Result<T, DecodeError>
{
let map = match self.toml.take() {
Some(Value::Table(table)) => table,
found => {
self.toml = found;
return Err(self.mismatch("table", &self.toml))
}
};
let amt = map.len();
let prev_iter = mem::replace(&mut self.cur_map,
map.into_iter().peekable());
let prev_map = mem::replace(&mut self.leftover_map, BTreeMap::new());
let ret = try!(f(self, amt));
let leftover = mem::replace(&mut self.leftover_map, prev_map);
self.cur_map = prev_iter;
if !leftover.is_empty() {
self.toml = Some(Value::Table(leftover));
}
Ok(ret)
}
fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
let key = match self.cur_map.peek().map(|p| p.0.clone()) {
Some(k) => k,
None => return Err(self.err(ExpectedMapKey(idx))),
};
let val = Value::String(key.clone());
f(&mut self.sub_decoder(Some(val), &key))
}
fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F)
-> Result<T, DecodeError>
where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
{
match self.cur_map.next() {
Some((key, value)) => {
let mut d = self.sub_decoder(Some(value), &key);
let ret = f(&mut d);
if let Some(toml) = d.toml.take() {
self.leftover_map.insert(key, toml);
}
ret
}
None => Err(self.err(ExpectedMapElement(idx))),
}
}
fn error(&mut self, err: &str) -> DecodeError {
DecodeError {
field: self.cur_field.clone(),
kind: ApplicationError(err.to_string())
}
}
}
#[cfg(test)]
mod tests {
use rustc_serialize::Decodable;
use std::collections::HashMap;
use {Parser, Decoder, Value};
#[test]
fn bad_enum_chooses_longest_error() {
#[derive(RustcDecodable)]
#[allow(dead_code)]
struct Foo {
wut: HashMap<String, Bar>,
}
#[derive(RustcDecodable)]
enum Bar {
Simple(String),
Detailed(Baz),
}
#[derive(RustcDecodable, Debug)]
struct Baz {
features: Vec<String>,
}
let s = r#"
[wut]
a = { features = "" }
"#;
let v = Parser::new(s).parse().unwrap();
let mut d = Decoder::new(Value::Table(v));
let err = match Foo::decode(&mut d) {
Ok(_) => panic!("expected error"),
Err(e) => e,
};
assert_eq!(err.field.as_ref().unwrap(), "wut.a.features");
}
}

773
third_party/rust/toml/src/decoder/serde.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,773 @@
use serde::de;
use Value;
use super::{Decoder, DecodeError, DecodeErrorKind};
use std::collections::BTreeMap;
macro_rules! forward_to_deserialize {
($(
$name:ident ( $( $arg:ident : $ty:ty ),* );
)*) => {
$(
forward_to_deserialize!{
func: $name ( $( $arg: $ty ),* );
}
)*
};
(func: deserialize_enum ( $( $arg:ident : $ty:ty ),* );) => {
fn deserialize_enum<V>(
&mut self,
$(_: $ty,)*
_visitor: V,
) -> ::std::result::Result<V::Value, Self::Error>
where V: ::serde::de::EnumVisitor
{
Err(::serde::de::Error::invalid_type(::serde::de::Type::Enum))
}
};
(func: $name:ident ( $( $arg:ident : $ty:ty ),* );) => {
#[inline]
fn $name<V>(
&mut self,
$(_: $ty,)*
visitor: V,
) -> ::std::result::Result<V::Value, Self::Error>
where V: ::serde::de::Visitor
{
self.deserialize(visitor)
}
};
}
impl de::Deserializer for Decoder {
type Error = DecodeError;
fn deserialize<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
match self.toml.take() {
Some(Value::String(s)) => visitor.visit_string(s),
Some(Value::Integer(i)) => visitor.visit_i64(i),
Some(Value::Float(f)) => visitor.visit_f64(f),
Some(Value::Boolean(b)) => visitor.visit_bool(b),
Some(Value::Datetime(s)) => visitor.visit_string(s),
Some(Value::Array(a)) => {
let len = a.len();
let iter = a.into_iter();
visitor.visit_seq(SeqDeserializer::new(iter, len, &mut self.toml))
}
Some(Value::Table(t)) => {
visitor.visit_map(MapVisitor {
iter: t.into_iter(),
de: self,
key: None,
value: None,
})
}
None => Err(self.err(DecodeErrorKind::EndOfStream)),
}
}
fn deserialize_bool<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
match self.toml.take() {
Some(Value::Boolean(b)) => visitor.visit_bool(b),
ref found => Err(self.mismatch("bool", found)),
}
}
fn deserialize_i8<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i16<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i64<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
match self.toml.take() {
Some(Value::Integer(f)) => visitor.visit_i64(f),
ref found => Err(self.mismatch("integer", found)),
}
}
fn deserialize_isize<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u8<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u16<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u64<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_usize<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_f32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_f64(visitor)
}
fn deserialize_f64<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
match self.toml.take() {
Some(Value::Float(f)) => visitor.visit_f64(f),
ref found => Err(self.mismatch("float", found)),
}
}
fn deserialize_str<V>(&mut self, mut visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor,
{
match self.toml.take() {
Some(Value::String(s)) => visitor.visit_string(s),
ref found => Err(self.mismatch("string", found)),
}
}
fn deserialize_string<V>(&mut self, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor,
{
self.deserialize_str(visitor)
}
fn deserialize_char<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
match self.toml.take() {
Some(Value::String(ref s)) if s.chars().count() == 1 => {
visitor.visit_char(s.chars().next().unwrap())
}
ref found => return Err(self.mismatch("string", found)),
}
}
fn deserialize_option<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
if self.toml.is_none() {
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_seq<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor,
{
if self.toml.is_none() {
let iter = None::<i32>.into_iter();
visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0))
} else {
self.deserialize(visitor)
}
}
fn deserialize_map<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor,
{
match self.toml.take() {
Some(Value::Table(t)) => {
visitor.visit_map(MapVisitor {
iter: t.into_iter(),
de: self,
key: None,
value: None,
})
}
ref found => Err(self.mismatch("table", found)),
}
}
fn deserialize_enum<V>(&mut self,
_enum: &str,
variants: &[&str],
mut visitor: V) -> Result<V::Value, DecodeError>
where V: de::EnumVisitor,
{
// When decoding enums, this crate takes the strategy of trying to
// decode the current TOML as all of the possible variants, returning
// success on the first one that succeeds.
//
// Note that fidelity of the errors returned here is a little nebulous,
// but we try to return the error that had the relevant field as the
// longest field. This way we hopefully match an error against what was
// most likely being written down without losing too much info.
let mut first_error = None::<DecodeError>;
for variant in 0..variants.len() {
let mut de = VariantVisitor {
de: self.sub_decoder(self.toml.clone(), ""),
variant: variant,
};
match visitor.visit(&mut de) {
Ok(value) => {
self.toml = de.de.toml;
return Ok(value);
}
Err(e) => {
if let Some(ref first) = first_error {
let my_len = e.field.as_ref().map(|s| s.len());
let first_len = first.field.as_ref().map(|s| s.len());
if my_len <= first_len {
continue
}
}
first_error = Some(e);
}
}
}
Err(first_error.unwrap_or_else(|| self.err(DecodeErrorKind::NoEnumVariants)))
}
// When #[derive(Deserialize)] encounters an unknown struct field it will
// call this method (somehow), and we want to preserve all unknown struct
// fields to return them upwards (to warn about unused keys), so we override
// that here to not tamper with our own internal state.
fn deserialize_ignored_any<V>(&mut self, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
use serde::de::value::ValueDeserializer;
let mut d = <() as ValueDeserializer<Self::Error>>::into_deserializer(());
d.deserialize(visitor)
}
fn deserialize_bytes<V>(&mut self, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_seq_fixed_size<V>(&mut self, _len: usize, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_newtype_struct<V>(&mut self, _name: &'static str, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(&mut self,
_name: &'static str,
_len: usize,
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_struct<V>(&mut self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_map(visitor)
}
fn deserialize_tuple<V>(&mut self,
_len: usize,
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
forward_to_deserialize!{
deserialize_unit();
deserialize_unit_struct(name: &'static str);
deserialize_struct_field();
}
}
struct VariantVisitor {
de: Decoder,
variant: usize,
}
impl de::VariantVisitor for VariantVisitor {
type Error = DecodeError;
fn visit_variant<V>(&mut self) -> Result<V, DecodeError>
where V: de::Deserialize
{
use serde::de::value::ValueDeserializer;
let mut de = self.variant.into_deserializer();
de::Deserialize::deserialize(&mut de)
}
fn visit_unit(&mut self) -> Result<(), DecodeError> {
de::Deserialize::deserialize(&mut self.de)
}
fn visit_newtype<T>(&mut self) -> Result<T, DecodeError>
where T: de::Deserialize,
{
de::Deserialize::deserialize(&mut self.de)
}
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, DecodeError>
where V: de::Visitor,
{
de::Deserializer::deserialize(&mut self.de, visitor)
}
fn visit_struct<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, DecodeError>
where V: de::Visitor,
{
de::Deserializer::deserialize(&mut self.de, visitor)
}
}
struct SeqDeserializer<'a, I> {
iter: I,
len: usize,
toml: &'a mut Option<Value>,
}
impl<'a, I> SeqDeserializer<'a, I> where I: Iterator<Item=Value> {
fn new(iter: I, len: usize, toml: &'a mut Option<Value>) -> Self {
SeqDeserializer {
iter: iter,
len: len,
toml: toml,
}
}
fn put_value_back(&mut self, v: Value) {
*self.toml = self.toml.take().or(Some(Value::Array(Vec::new())));
match self.toml.as_mut().unwrap() {
&mut Value::Array(ref mut a) => {
a.push(v);
},
_ => unreachable!(),
}
}
}
impl<'a, I> de::Deserializer for SeqDeserializer<'a, I>
where I: Iterator<Item=Value>,
{
type Error = DecodeError;
fn deserialize<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor,
{
visitor.visit_seq(self)
}
forward_to_deserialize!{
deserialize_bool();
deserialize_usize();
deserialize_u8();
deserialize_u16();
deserialize_u32();
deserialize_u64();
deserialize_isize();
deserialize_i8();
deserialize_i16();
deserialize_i32();
deserialize_i64();
deserialize_f32();
deserialize_f64();
deserialize_char();
deserialize_str();
deserialize_string();
deserialize_unit();
deserialize_option();
deserialize_seq();
deserialize_seq_fixed_size(len: usize);
deserialize_bytes();
deserialize_map();
deserialize_unit_struct(name: &'static str);
deserialize_newtype_struct(name: &'static str);
deserialize_tuple_struct(name: &'static str, len: usize);
deserialize_struct(name: &'static str, fields: &'static [&'static str]);
deserialize_struct_field();
deserialize_tuple(len: usize);
deserialize_enum(name: &'static str, variants: &'static [&'static str]);
deserialize_ignored_any();
}
}
impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I>
where I: Iterator<Item=Value>
{
type Error = DecodeError;
fn visit<V>(&mut self) -> Result<Option<V>, DecodeError>
where V: de::Deserialize
{
match self.iter.next() {
Some(value) => {
self.len -= 1;
let mut de = Decoder::new(value);
let v = try!(de::Deserialize::deserialize(&mut de));
if let Some(t) = de.toml {
self.put_value_back(t);
}
Ok(Some(v))
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), DecodeError> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl de::Error for DecodeError {
fn custom<T: Into<String>>(msg: T) -> DecodeError {
DecodeError {
field: None,
kind: DecodeErrorKind::CustomError(msg.into()),
}
}
fn end_of_stream() -> DecodeError {
DecodeError { field: None, kind: DecodeErrorKind::EndOfStream }
}
fn missing_field(name: &'static str) -> DecodeError {
DecodeError {
field: Some(name.to_string()),
kind: DecodeErrorKind::ExpectedField(None),
}
}
fn unknown_field(name: &str) -> DecodeError {
DecodeError {
field: Some(name.to_string()),
kind: DecodeErrorKind::UnknownField,
}
}
fn invalid_type(ty: de::Type) -> Self {
DecodeError {
field: None,
kind: DecodeErrorKind::InvalidType(match ty {
de::Type::Bool => "bool",
de::Type::Usize |
de::Type::U8 |
de::Type::U16 |
de::Type::U32 |
de::Type::U64 |
de::Type::Isize |
de::Type::I8 |
de::Type::I16 |
de::Type::I32 |
de::Type::I64 => "integer",
de::Type::F32 |
de::Type::F64 => "float",
de::Type::Char |
de::Type::Str |
de::Type::String => "string",
de::Type::Seq => "array",
de::Type::Struct |
de::Type::Map => "table",
de::Type::Unit => "Unit",
de::Type::Option => "Option",
de::Type::UnitStruct => "UnitStruct",
de::Type::NewtypeStruct => "NewtypeStruct",
de::Type::TupleStruct => "TupleStruct",
de::Type::FieldName => "FieldName",
de::Type::Tuple => "Tuple",
de::Type::Enum => "Enum",
de::Type::VariantName => "VariantName",
de::Type::StructVariant => "StructVariant",
de::Type::TupleVariant => "TupleVariant",
de::Type::UnitVariant => "UnitVariant",
de::Type::Bytes => "Bytes",
})
}
}
}
struct MapVisitor<'a, I> {
iter: I,
de: &'a mut Decoder,
key: Option<String>,
value: Option<Value>,
}
impl<'a, I> MapVisitor<'a, I> {
fn put_value_back(&mut self, v: Value) {
self.de.toml = self.de.toml.take().or_else(|| {
Some(Value::Table(BTreeMap::new()))
});
match self.de.toml.as_mut().unwrap() {
&mut Value::Table(ref mut t) => {
t.insert(self.key.take().unwrap(), v);
},
_ => unreachable!(),
}
}
}
impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
where I: Iterator<Item=(String, Value)>
{
type Error = DecodeError;
fn visit_key<K>(&mut self) -> Result<Option<K>, DecodeError>
where K: de::Deserialize
{
while let Some((k, v)) = self.iter.next() {
let mut dec = self.de.sub_decoder(Some(Value::String(k.clone())), &k);
self.key = Some(k);
match de::Deserialize::deserialize(&mut dec) {
Ok(val) => {
self.value = Some(v);
return Ok(Some(val))
}
// If this was an unknown field, then we put the toml value
// back into the map and keep going.
Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => {
self.put_value_back(v);
}
Err(e) => return Err(e),
}
}
Ok(None)
}
fn visit_value<V>(&mut self) -> Result<V, DecodeError>
where V: de::Deserialize
{
match self.value.take() {
Some(t) => {
let mut dec = {
// Borrowing the key here because Rust doesn't have
// non-lexical borrows yet.
let key = match self.key {
Some(ref key) => &**key,
None => ""
};
self.de.sub_decoder(Some(t), key)
};
let v = try!(de::Deserialize::deserialize(&mut dec));
if let Some(t) = dec.toml {
self.put_value_back(t);
}
Ok(v)
},
None => Err(de::Error::end_of_stream())
}
}
fn end(&mut self) -> Result<(), DecodeError> {
if let Some(v) = self.value.take() {
self.put_value_back(v);
}
while let Some((k, v)) = self.iter.next() {
self.key = Some(k);
self.put_value_back(v);
}
Ok(())
}
fn missing_field<V>(&mut self, field_name: &'static str)
-> Result<V, DecodeError> where V: de::Deserialize {
// See if the type can deserialize from a unit.
match de::Deserialize::deserialize(&mut UnitDeserializer) {
Err(DecodeError {
kind: DecodeErrorKind::InvalidType(..),
field,
}) => Err(DecodeError {
field: field.or(Some(field_name.to_string())),
kind: DecodeErrorKind::ExpectedField(None),
}),
v => v,
}
}
}
struct UnitDeserializer;
impl de::Deserializer for UnitDeserializer {
type Error = DecodeError;
fn deserialize<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor,
{
visitor.visit_unit()
}
fn deserialize_option<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor,
{
visitor.visit_none()
}
forward_to_deserialize!{
deserialize_bool();
deserialize_usize();
deserialize_u8();
deserialize_u16();
deserialize_u32();
deserialize_u64();
deserialize_isize();
deserialize_i8();
deserialize_i16();
deserialize_i32();
deserialize_i64();
deserialize_f32();
deserialize_f64();
deserialize_char();
deserialize_str();
deserialize_string();
deserialize_unit();
deserialize_seq();
deserialize_seq_fixed_size(len: usize);
deserialize_bytes();
deserialize_map();
deserialize_unit_struct(name: &'static str);
deserialize_newtype_struct(name: &'static str);
deserialize_tuple_struct(name: &'static str, len: usize);
deserialize_struct(name: &'static str, fields: &'static [&'static str]);
deserialize_struct_field();
deserialize_tuple(len: usize);
deserialize_enum(name: &'static str, variants: &'static [&'static str]);
deserialize_ignored_any();
}
}
impl de::Deserialize for Value {
fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error>
where D: de::Deserializer
{
struct ValueVisitor;
impl de::Visitor for ValueVisitor {
type Value = Value;
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
Ok(Value::Boolean(value))
}
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
Ok(Value::Integer(value))
}
fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
Ok(Value::Float(value))
}
fn visit_str<E>(&mut self, value: &str) -> Result<Value, E> {
Ok(Value::String(value.into()))
}
fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
Ok(Value::String(value))
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::SeqVisitor
{
let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
Ok(Value::Array(values))
}
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::MapVisitor
{
let mut v = de::impls::BTreeMapVisitor::new();
let values = try!(v.visit_map(visitor));
Ok(Value::Table(values))
}
}
deserializer.deserialize(ValueVisitor)
}
}

209
third_party/rust/toml/src/display.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,209 @@
use std::fmt;
use Table as TomlTable;
use Value::{self, String, Integer, Float, Boolean, Datetime, Array, Table};
struct Printer<'a, 'b:'a> {
output: &'a mut fmt::Formatter<'b>,
stack: Vec<&'a str>,
}
struct Key<'a>(&'a [&'a str]);
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
String(ref s) => write_str(f, s),
Integer(i) => write!(f, "{}", i),
Float(fp) => {
try!(write!(f, "{}", fp));
if fp % 1.0 == 0.0 { try!(write!(f, ".0")) }
Ok(())
}
Boolean(b) => write!(f, "{}", b),
Datetime(ref s) => write!(f, "{}", s),
Table(ref t) => {
let mut p = Printer { output: f, stack: Vec::new() };
p.print(t)
}
Array(ref a) => {
try!(write!(f, "["));
for (i, v) in a.iter().enumerate() {
if i != 0 { try!(write!(f, ", ")); }
try!(write!(f, "{}", v));
}
write!(f, "]")
}
}
}
}
fn write_str(f: &mut fmt::Formatter, s: &str) -> fmt::Result {
try!(write!(f, "\""));
for ch in s.chars() {
match ch {
'\u{8}' => try!(write!(f, "\\b")),
'\u{9}' => try!(write!(f, "\\t")),
'\u{a}' => try!(write!(f, "\\n")),
'\u{c}' => try!(write!(f, "\\f")),
'\u{d}' => try!(write!(f, "\\r")),
'\u{22}' => try!(write!(f, "\\\"")),
'\u{5c}' => try!(write!(f, "\\\\")),
ch => try!(write!(f, "{}", ch)),
}
}
write!(f, "\"")
}
impl<'a, 'b> Printer<'a, 'b> {
fn print(&mut self, table: &'a TomlTable) -> fmt::Result {
let mut space_out_first = false;
for (k, v) in table.iter() {
match *v {
Table(..) => continue,
Array(ref a) => {
if let Some(&Table(..)) = a.first() {
continue;
}
}
_ => {}
}
space_out_first = true;
try!(writeln!(self.output, "{} = {}", Key(&[k]), v));
}
for (i, (k, v)) in table.iter().enumerate() {
match *v {
Table(ref inner) => {
self.stack.push(k);
if space_out_first || i != 0 {
try!(write!(self.output, "\n"));
}
try!(writeln!(self.output, "[{}]", Key(&self.stack)));
try!(self.print(inner));
self.stack.pop();
}
Array(ref inner) => {
match inner.first() {
Some(&Table(..)) => {}
_ => continue
}
self.stack.push(k);
for (j, inner) in inner.iter().enumerate() {
if space_out_first || i != 0 || j != 0 {
try!(write!(self.output, "\n"));
}
try!(writeln!(self.output, "[[{}]]", Key(&self.stack)));
match *inner {
Table(ref inner) => try!(self.print(inner)),
_ => panic!("non-heterogeneous toml array"),
}
}
self.stack.pop();
}
_ => {},
}
}
Ok(())
}
}
impl<'a> fmt::Display for Key<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, part) in self.0.iter().enumerate() {
if i != 0 { try!(write!(f, ".")); }
let ok = part.chars().all(|c| {
match c {
'a' ... 'z' |
'A' ... 'Z' |
'0' ... '9' |
'-' | '_' => true,
_ => false,
}
});
if ok {
try!(write!(f, "{}", part));
} else {
try!(write_str(f, part));
}
}
Ok(())
}
}
#[cfg(test)]
#[allow(warnings)]
mod tests {
use Value;
use Value::{String, Integer, Float, Boolean, Datetime, Array, Table};
use std::collections::BTreeMap;
macro_rules! map( ($($k:expr => $v:expr),*) => ({
let mut _m = BTreeMap::new();
$(_m.insert($k.to_string(), $v);)*
_m
}) );
#[test]
fn simple_show() {
assert_eq!(String("foo".to_string()).to_string(),
"\"foo\"");
assert_eq!(Integer(10).to_string(),
"10");
assert_eq!(Float(10.0).to_string(),
"10.0");
assert_eq!(Float(2.4).to_string(),
"2.4");
assert_eq!(Boolean(true).to_string(),
"true");
assert_eq!(Datetime("test".to_string()).to_string(),
"test");
assert_eq!(Array(vec![]).to_string(),
"[]");
assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string(),
"[1, 2]");
}
#[test]
fn table() {
assert_eq!(Table(map! { }).to_string(),
"");
assert_eq!(Table(map! { "test" => Integer(2) }).to_string(),
"test = 2\n");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Table(map! {
"test" => String("wut".to_string())
})
}).to_string(),
"test = 2\n\
\n\
[test2]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Table(map! {
"test" => String("wut".to_string())
})
}).to_string(),
"test = 2\n\
\n\
[test2]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Array(vec![Table(map! {
"test" => String("wut".to_string())
})])
}).to_string(),
"test = 2\n\
\n\
[[test2]]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"foo.bar" => Integer(2),
"foo\"bar" => Integer(2)
}).to_string(),
"\"foo\\\"bar\" = 2\n\
\"foo.bar\" = 2\n");
}
}

203
third_party/rust/toml/src/encoder/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,203 @@
use std::collections::BTreeMap;
use std::error;
use std::fmt;
use std::mem;
use {Value, Table};
#[cfg(feature = "rustc-serialize")] mod rustc_serialize;
#[cfg(feature = "serde")] mod serde;
/// A structure to transform Rust values into TOML values.
///
/// This encoder implements the serialization `Encoder` interface, allowing
/// `Encodable` rust types to be fed into the encoder. The output of this
/// encoder is a TOML `Table` structure. The resulting TOML can be stringified
/// if necessary.
///
/// # Example
///
/// ```
/// extern crate rustc_serialize;
/// extern crate toml;
///
/// # fn main() {
/// use toml::{Encoder, Value};
/// use rustc_serialize::Encodable;
///
/// #[derive(RustcEncodable)]
/// struct MyStruct { foo: isize, bar: String }
/// let my_struct = MyStruct { foo: 4, bar: "hello!".to_string() };
///
/// let mut e = Encoder::new();
/// my_struct.encode(&mut e).unwrap();
///
/// assert_eq!(e.toml.get(&"foo".to_string()), Some(&Value::Integer(4)))
/// # }
/// ```
#[derive(Default, Debug)]
pub struct Encoder {
/// Output TOML that is emitted. The current version of this encoder forces
/// the top-level representation of a structure to be a table.
///
/// This field can be used to extract the return value after feeding a value
/// into this `Encoder`.
pub toml: Table,
state: State,
}
/// Enumeration of errors which can occur while encoding a rust value into a
/// TOML value.
#[allow(missing_copy_implementations)]
#[derive(Debug)]
pub enum Error {
/// Indication that a key was needed when a value was emitted, but no key
/// was previously emitted.
NeedsKey,
/// Indication that a key was emitted, but no value was emitted.
NoValue,
/// Indicates that a map key was attempted to be emitted at an invalid
/// location.
InvalidMapKeyLocation,
/// Indicates that a type other than a string was attempted to be used as a
/// map key type.
InvalidMapKeyType,
/// A custom error type was generated
Custom(String),
}
/// Internal state of the encoder when encoding transitions
#[derive(Debug)]
pub struct EncoderState {
inner: State,
}
#[derive(PartialEq, Debug)]
enum State {
Start,
NextKey(String),
NextArray(Vec<Value>),
NextMapKey,
}
impl Default for State {
fn default() -> State { State::Start }
}
impl Encoder {
/// Constructs a new encoder which will emit to the given output stream.
pub fn new() -> Encoder {
Encoder { state: State::Start, toml: BTreeMap::new() }
}
fn emit_value(&mut self, v: Value) -> Result<(), Error> {
match mem::replace(&mut self.state, State::Start) {
State::NextKey(key) => { self.toml.insert(key, v); Ok(()) }
State::NextArray(mut vec) => {
// TODO: validate types
vec.push(v);
self.state = State::NextArray(vec);
Ok(())
}
State::NextMapKey => {
match v {
Value::String(s) => { self.state = State::NextKey(s); Ok(()) }
_ => Err(Error::InvalidMapKeyType)
}
}
_ => Err(Error::NeedsKey)
}
}
fn emit_none(&mut self) -> Result<(), Error> {
match mem::replace(&mut self.state, State::Start) {
State::Start => unreachable!(),
State::NextKey(_) => Ok(()),
State::NextArray(..) => panic!("how to encode None in an array?"),
State::NextMapKey => Err(Error::InvalidMapKeyLocation),
}
}
fn seq_begin(&mut self) -> Result<State, Error> {
Ok(mem::replace(&mut self.state, State::NextArray(Vec::new())))
}
fn seq_end(&mut self, old: State) -> Result<(), Error> {
match mem::replace(&mut self.state, old) {
State::NextArray(v) => self.emit_value(Value::Array(v)),
_ => unreachable!(),
}
}
fn table_key<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
match mem::replace(&mut self.state, State::NextMapKey) {
State::Start => {}
_ => return Err(Error::InvalidMapKeyLocation),
}
try!(f(self));
match self.state {
State::NextKey(_) => Ok(()),
_ => Err(Error::InvalidMapKeyLocation),
}
}
}
/// Encodes an encodable value into a TOML value.
///
/// This function expects the type given to represent a TOML table in some form.
/// If encoding encounters an error, then this function will fail the task.
#[cfg(feature = "rustc-serialize")]
pub fn encode<T: ::rustc_serialize::Encodable>(t: &T) -> Value {
let mut e = Encoder::new();
t.encode(&mut e).unwrap();
Value::Table(e.toml)
}
/// Encodes an encodable value into a TOML value.
///
/// This function expects the type given to represent a TOML table in some form.
/// If encoding encounters an error, then this function will fail the task.
#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))]
pub fn encode<T: ::serde::Serialize>(t: &T) -> Value {
let mut e = Encoder::new();
t.serialize(&mut e).unwrap();
Value::Table(e.toml)
}
/// Encodes an encodable value into a TOML string.
///
/// This function expects the type given to represent a TOML table in some form.
/// If encoding encounters an error, then this function will fail the task.
#[cfg(feature = "rustc-serialize")]
pub fn encode_str<T: ::rustc_serialize::Encodable>(t: &T) -> String {
encode(t).to_string()
}
/// Encodes an encodable value into a TOML string.
///
/// This function expects the type given to represent a TOML table in some form.
/// If encoding encounters an error, then this function will fail the task.
#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))]
pub fn encode_str<T: ::serde::Serialize>(t: &T) -> String {
encode(t).to_string()
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::NeedsKey => write!(f, "need a key to encode"),
Error::NoValue => write!(f, "no value to emit for a previous key"),
Error::InvalidMapKeyLocation => write!(f, "a map cannot be emitted \
at this location"),
Error::InvalidMapKeyType => write!(f, "only strings can be used as \
key types"),
Error::Custom(ref s) => write!(f, "custom error: {}", s),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str { "TOML encoding error" }
}

748
third_party/rust/toml/src/encoder/rustc_serialize.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,748 @@
use std::mem;
use rustc_serialize;
use Value;
use super::{Encoder, Error, State};
use super::Error::*;
impl Encoder {
fn table<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
match mem::replace(&mut self.state, State::Start) {
State::NextKey(key) => {
let mut nested = Encoder::new();
try!(f(&mut nested));
self.toml.insert(key, Value::Table(nested.toml));
Ok(())
}
State::NextArray(mut arr) => {
let mut nested = Encoder::new();
try!(f(&mut nested));
arr.push(Value::Table(nested.toml));
self.state = State::NextArray(arr);
Ok(())
}
State::Start => f(self),
State::NextMapKey => Err(Error::InvalidMapKeyLocation),
}
}
fn seq<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
let old = try!(self.seq_begin());
try!(f(self));
self.seq_end(old)
}
}
impl rustc_serialize::Encoder for Encoder {
type Error = Error;
fn emit_nil(&mut self) -> Result<(), Error> { Ok(()) }
fn emit_usize(&mut self, v: usize) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_u8(&mut self, v: u8) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_u16(&mut self, v: u16) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_u32(&mut self, v: u32) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_u64(&mut self, v: u64) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_isize(&mut self, v: isize) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_i8(&mut self, v: i8) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_i16(&mut self, v: i16) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_i32(&mut self, v: i32) -> Result<(), Error> {
self.emit_i64(v as i64)
}
fn emit_i64(&mut self, v: i64) -> Result<(), Error> {
self.emit_value(Value::Integer(v))
}
fn emit_bool(&mut self, v: bool) -> Result<(), Error> {
self.emit_value(Value::Boolean(v))
}
fn emit_f32(&mut self, v: f32) -> Result<(), Error> { self.emit_f64(v as f64) }
fn emit_f64(&mut self, v: f64) -> Result<(), Error> {
self.emit_value(Value::Float(v))
}
fn emit_char(&mut self, v: char) -> Result<(), Error> {
self.emit_str(&v.to_string())
}
fn emit_str(&mut self, v: &str) -> Result<(), Error> {
self.emit_value(Value::String(v.to_string()))
}
fn emit_enum<F>(&mut self, _name: &str, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
fn emit_enum_variant<F>(&mut self, _v_name: &str, _v_id: usize,
_len: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
fn emit_enum_variant_arg<F>(&mut self, _a_idx: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
fn emit_enum_struct_variant<F>(&mut self, _v_name: &str, _v_id: usize,
_len: usize,
_f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
panic!()
}
fn emit_enum_struct_variant_field<F>(&mut self,
_f_name: &str,
_f_idx: usize,
_f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
panic!()
}
fn emit_struct<F>(&mut self, _name: &str, _len: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
self.table(f)
}
fn emit_struct_field<F>(&mut self, f_name: &str, _f_idx: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
let old = mem::replace(&mut self.state,
State::NextKey(f_name.to_string()));
try!(f(self));
if self.state != State::Start {
return Err(NoValue)
}
self.state = old;
Ok(())
}
fn emit_tuple<F>(&mut self, len: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
self.emit_seq(len, f)
}
fn emit_tuple_arg<F>(&mut self, idx: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
self.emit_seq_elt(idx, f)
}
fn emit_tuple_struct<F>(&mut self, _name: &str, _len: usize, _f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
unimplemented!()
}
fn emit_tuple_struct_arg<F>(&mut self, _f_idx: usize, _f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
unimplemented!()
}
fn emit_option<F>(&mut self, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
fn emit_option_none(&mut self) -> Result<(), Error> {
self.emit_none()
}
fn emit_option_some<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
fn emit_seq<F>(&mut self, _len: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
self.seq(f)
}
fn emit_seq_elt<F>(&mut self, _idx: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
fn emit_map<F>(&mut self, len: usize, f: F)
-> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
self.emit_struct("foo", len, f)
}
fn emit_map_elt_key<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
self.table_key(f)
}
fn emit_map_elt_val<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error>
{
f(self)
}
}
impl rustc_serialize::Encodable for Value {
fn encode<E>(&self, e: &mut E) -> Result<(), E::Error>
where E: rustc_serialize::Encoder
{
match *self {
Value::String(ref s) => e.emit_str(s),
Value::Integer(i) => e.emit_i64(i),
Value::Float(f) => e.emit_f64(f),
Value::Boolean(b) => e.emit_bool(b),
Value::Datetime(ref s) => e.emit_str(s),
Value::Array(ref a) => {
e.emit_seq(a.len(), |e| {
for item in a {
try!(item.encode(e));
}
Ok(())
})
}
Value::Table(ref t) => {
e.emit_map(t.len(), |e| {
for (i, (key, value)) in t.iter().enumerate() {
try!(e.emit_map_elt_key(i, |e| e.emit_str(key)));
try!(e.emit_map_elt_val(i, |e| value.encode(e)));
}
Ok(())
})
}
}
}
}
#[cfg(test)]
mod tests {
use std::collections::{BTreeMap, HashSet};
use rustc_serialize::{self, Encodable, Decodable};
use {Encoder, Decoder, DecodeError};
use Value;
use Value::{Table, Integer, Array, Float};
macro_rules! encode( ($t:expr) => ({
let mut e = Encoder::new();
$t.encode(&mut e).unwrap();
e.toml
}) );
macro_rules! decode( ($t:expr) => ({
let mut d = Decoder::new($t);
Decodable::decode(&mut d).unwrap()
}) );
macro_rules! map( ($($k:ident, $v:expr),*) => ({
let mut _m = BTreeMap::new();
$(_m.insert(stringify!($k).to_string(), $v);)*
_m
}) );
#[test]
fn smoke() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: isize }
let v = Foo { a: 2 };
assert_eq!(encode!(v), map! { a, Integer(2) });
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn smoke_hyphen() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a_b: isize }
let v = Foo { a_b: 2 };
assert_eq!(encode!(v), map! { a_b, Integer(2) });
assert_eq!(v, decode!(Table(encode!(v))));
let mut m = BTreeMap::new();
m.insert("a-b".to_string(), Integer(2));
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn nested() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: isize, b: Bar }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar { a: String }
let v = Foo { a: 2, b: Bar { a: "test".to_string() } };
assert_eq!(encode!(v),
map! {
a, Integer(2),
b, Table(map! {
a, Value::String("test".to_string())
})
});
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn application_decode_error() {
#[derive(PartialEq, Debug)]
struct Range10(usize);
impl Decodable for Range10 {
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<Range10, D::Error> {
let x: usize = try!(Decodable::decode(d));
if x > 10 {
Err(d.error("Value out of range!"))
} else {
Ok(Range10(x))
}
}
}
let mut d_good = Decoder::new(Integer(5));
let mut d_bad1 = Decoder::new(Value::String("not an isize".to_string()));
let mut d_bad2 = Decoder::new(Integer(11));
assert_eq!(Ok(Range10(5)), Decodable::decode(&mut d_good));
let err1: Result<Range10, _> = Decodable::decode(&mut d_bad1);
assert!(err1.is_err());
let err2: Result<Range10, _> = Decodable::decode(&mut d_bad2);
assert!(err2.is_err());
}
#[test]
fn array() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Vec<isize> }
let v = Foo { a: vec![1, 2, 3, 4] };
assert_eq!(encode!(v),
map! {
a, Array(vec![
Integer(1),
Integer(2),
Integer(3),
Integer(4)
])
});
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn tuple() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: (isize, isize, isize, isize) }
let v = Foo { a: (1, 2, 3, 4) };
assert_eq!(encode!(v),
map! {
a, Array(vec![
Integer(1),
Integer(2),
Integer(3),
Integer(4)
])
});
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn inner_structs_with_options() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo {
a: Option<Box<Foo>>,
b: Bar,
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar {
a: String,
b: f64,
}
let v = Foo {
a: Some(Box::new(Foo {
a: None,
b: Bar { a: "foo".to_string(), b: 4.5 },
})),
b: Bar { a: "bar".to_string(), b: 1.0 },
};
assert_eq!(encode!(v),
map! {
a, Table(map! {
b, Table(map! {
a, Value::String("foo".to_string()),
b, Float(4.5)
})
}),
b, Table(map! {
a, Value::String("bar".to_string()),
b, Float(1.0)
})
});
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn hashmap() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo {
map: BTreeMap<String, isize>,
set: HashSet<char>,
}
let v = Foo {
map: {
let mut m = BTreeMap::new();
m.insert("foo".to_string(), 10);
m.insert("bar".to_string(), 4);
m
},
set: {
let mut s = HashSet::new();
s.insert('a');
s
},
};
assert_eq!(encode!(v),
map! {
map, Table(map! {
foo, Integer(10),
bar, Integer(4)
}),
set, Array(vec![Value::String("a".to_string())])
}
);
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn tuple_struct() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo(isize, String, f64);
let v = Foo(1, "foo".to_string(), 4.5);
assert_eq!(
encode!(v),
map! {
_field0, Integer(1),
_field1, Value::String("foo".to_string()),
_field2, Float(4.5)
}
);
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn table_array() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Vec<Bar>, }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar { a: isize }
let v = Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] };
assert_eq!(
encode!(v),
map! {
a, Array(vec![
Table(map!{ a, Integer(1) }),
Table(map!{ a, Integer(2) }),
])
}
);
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn type_errors() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { bar: isize }
let mut d = Decoder::new(Table(map! {
bar, Float(1.0)
}));
let a: Result<Foo, DecodeError> = Decodable::decode(&mut d);
match a {
Ok(..) => panic!("should not have decoded"),
Err(e) => {
assert_eq!(e.to_string(),
"expected a value of type `integer`, but \
found a value of type `float` for the key `bar`");
}
}
}
#[test]
fn missing_errors() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { bar: isize }
let mut d = Decoder::new(Table(map! {
}));
let a: Result<Foo, DecodeError> = Decodable::decode(&mut d);
match a {
Ok(..) => panic!("should not have decoded"),
Err(e) => {
assert_eq!(e.to_string(),
"expected a value of type `integer` for the key `bar`");
}
}
}
#[test]
fn parse_enum() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: E }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
enum E {
Bar(isize),
Baz(f64),
Last(Foo2),
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo2 {
test: String,
}
let v = Foo { a: E::Bar(10) };
assert_eq!(
encode!(v),
map! { a, Integer(10) }
);
assert_eq!(v, decode!(Table(encode!(v))));
let v = Foo { a: E::Baz(10.2) };
assert_eq!(
encode!(v),
map! { a, Float(10.2) }
);
assert_eq!(v, decode!(Table(encode!(v))));
let v = Foo { a: E::Last(Foo2 { test: "test".to_string() }) };
assert_eq!(
encode!(v),
map! { a, Table(map! { test, Value::String("test".to_string()) }) }
);
assert_eq!(v, decode!(Table(encode!(v))));
}
#[test]
fn unused_fields() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: isize }
let v = Foo { a: 2 };
let mut d = Decoder::new(Table(map! {
a, Integer(2),
b, Integer(5)
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! {
b, Integer(5)
})));
}
#[test]
fn unused_fields2() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Bar }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar { a: isize }
let v = Foo { a: Bar { a: 2 } };
let mut d = Decoder::new(Table(map! {
a, Table(map! {
a, Integer(2),
b, Integer(5)
})
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! {
a, Table(map! {
b, Integer(5)
})
})));
}
#[test]
fn unused_fields3() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Bar }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar { a: isize }
let v = Foo { a: Bar { a: 2 } };
let mut d = Decoder::new(Table(map! {
a, Table(map! {
a, Integer(2)
})
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, None);
}
#[test]
fn unused_fields4() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: BTreeMap<String, String> }
let v = Foo { a: map! { a, "foo".to_string() } };
let mut d = Decoder::new(Table(map! {
a, Table(map! {
a, Value::String("foo".to_string())
})
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, None);
}
#[test]
fn unused_fields5() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Vec<String> }
let v = Foo { a: vec!["a".to_string()] };
let mut d = Decoder::new(Table(map! {
a, Array(vec![Value::String("a".to_string())])
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, None);
}
#[test]
fn unused_fields6() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Option<Vec<String>> }
let v = Foo { a: Some(vec![]) };
let mut d = Decoder::new(Table(map! {
a, Array(vec![])
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, None);
}
#[test]
fn unused_fields7() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Vec<Bar> }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar { a: isize }
let v = Foo { a: vec![Bar { a: 1 }] };
let mut d = Decoder::new(Table(map! {
a, Array(vec![Table(map! {
a, Integer(1),
b, Integer(2)
})])
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! {
a, Array(vec![Table(map! {
b, Integer(2)
})])
})));
}
#[test]
fn unused_fields8() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: BTreeMap<String, Bar> }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar { a: isize }
let v = Foo { a: map! { a, Bar { a: 2 } } };
let mut d = Decoder::new(Table(map! {
a, Table(map! {
a, Table(map! {
a, Integer(2),
b, Integer(2)
})
})
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
assert_eq!(d.toml, Some(Table(map! {
a, Table(map! {
a, Table(map! {
b, Integer(2)
})
})
})));
}
#[test]
fn empty_arrays() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Vec<Bar> }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar;
let v = Foo { a: vec![] };
let mut d = Decoder::new(Table(map! {}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
}
#[test]
fn empty_arrays2() {
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Foo { a: Option<Vec<Bar>> }
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
struct Bar;
let v = Foo { a: None };
let mut d = Decoder::new(Table(map! {}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
let v = Foo { a: Some(vec![]) };
let mut d = Decoder::new(Table(map! {
a, Array(vec![])
}));
assert_eq!(v, Decodable::decode(&mut d).unwrap());
}
#[test]
fn round_trip() {
let toml = r#"
[test]
foo = "bar"
[[values]]
foo = "baz"
[[values]]
foo = "qux"
"#;
let value: Value = toml.parse().unwrap();
let val2 = ::encode_str(&value).parse().unwrap();
assert_eq!(value, val2);
}
}

339
third_party/rust/toml/src/encoder/serde.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,339 @@
use std::mem;
use serde::ser;
use Value;
use super::{Encoder, Error, EncoderState, State};
impl Encoder {
fn table_begin(&mut self) -> Result<Self, Error> {
match self.state {
State::NextMapKey => Err(Error::InvalidMapKeyLocation),
_ => Ok(mem::replace(self, Encoder::new()))
}
}
fn table_end(&mut self, mut state: Self) -> Result<(), Error> {
match state.state {
State::NextKey(key) => {
mem::swap(&mut self.toml, &mut state.toml);
self.toml.insert(key, Value::Table(state.toml));
},
State::NextArray(mut arr) => {
mem::swap(&mut self.toml, &mut state.toml);
arr.push(Value::Table(state.toml));
self.state = State::NextArray(arr);
},
State::Start => {},
State::NextMapKey => unreachable!(),
}
Ok(())
}
}
impl ser::Serializer for Encoder {
type Error = Error;
type MapState = Self;
type StructState = Self;
type StructVariantState = Self;
type SeqState = EncoderState;
type TupleState = EncoderState;
type TupleStructState = EncoderState;
type TupleVariantState = EncoderState;
fn serialize_bool(&mut self, v: bool) -> Result<(), Error> {
self.emit_value(Value::Boolean(v))
}
fn serialize_i64(&mut self, v: i64) -> Result<(), Error> {
self.emit_value(Value::Integer(v))
}
// TODO: checked casts
fn serialize_u64(&mut self, v: u64) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_isize(&mut self, v: isize) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_usize(&mut self, v: usize) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_i8(&mut self, v: i8) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_u8(&mut self, v: u8) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_i16(&mut self, v: i16) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_u16(&mut self, v: u16) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_i32(&mut self, v: i32) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_u32(&mut self, v: u32) -> Result<(), Error> {
self.serialize_i64(v as i64)
}
fn serialize_f32(&mut self, v: f32) -> Result<(), Error> {
self.serialize_f64(v as f64)
}
fn serialize_f64(&mut self, v: f64) -> Result<(), Error> {
self.emit_value(Value::Float(v))
}
fn serialize_str(&mut self, value: &str) -> Result<(), Error> {
self.emit_value(Value::String(value.to_string()))
}
fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<(), Error> {
Ok(())
}
fn serialize_unit(&mut self) -> Result<(), Error> {
Ok(())
}
fn serialize_none(&mut self) -> Result<(), Error> {
self.emit_none()
}
fn serialize_char(&mut self, c: char) -> Result<(), Error> {
self.serialize_str(&c.to_string())
}
fn serialize_some<V>(&mut self, value: V) -> Result<(), Error>
where V: ser::Serialize
{
value.serialize(self)
}
fn serialize_bytes(&mut self, v: &[u8]) -> Result<(), Error> {
let mut state = try!(self.serialize_seq(Some(v.len())));
for c in v {
try!(self.serialize_seq_elt(&mut state, c));
}
self.serialize_seq_end(state)
}
fn serialize_seq_fixed_size(&mut self, len: usize)
-> Result<EncoderState, Error> {
self.serialize_seq(Some(len))
}
fn serialize_seq(&mut self, _len: Option<usize>)
-> Result<EncoderState, Error> {
self.seq_begin().map(|s| EncoderState { inner: s })
}
fn serialize_seq_elt<T>(&mut self,
_state: &mut EncoderState,
value: T) -> Result<(), Error>
where T: ser::Serialize
{
value.serialize(self)
}
fn serialize_seq_end(&mut self, state: EncoderState) -> Result<(), Error> {
self.seq_end(state.inner)
}
fn serialize_tuple(&mut self, len: usize)
-> Result<EncoderState, Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_elt<T>(&mut self,
state: &mut EncoderState,
value: T) -> Result<(), Error>
where T: ser::Serialize
{
self.serialize_seq_elt(state, value)
}
fn serialize_tuple_end(&mut self, state: EncoderState) -> Result<(), Error> {
self.serialize_seq_end(state)
}
fn serialize_tuple_struct(&mut self,
_name: &'static str,
len: usize) -> Result<EncoderState, Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct_elt<T>(&mut self,
state: &mut EncoderState,
value: T) -> Result<(), Error>
where T: ser::Serialize
{
self.serialize_seq_elt(state, value)
}
fn serialize_tuple_struct_end(&mut self, state: EncoderState)
-> Result<(), Error> {
self.serialize_seq_end(state)
}
fn serialize_tuple_variant(&mut self,
_name: &'static str,
_id: usize,
_variant: &'static str,
len: usize) -> Result<EncoderState, Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant_elt<T>(&mut self,
state: &mut EncoderState,
value: T) -> Result<(), Error>
where T: ser::Serialize
{
self.serialize_seq_elt(state, value)
}
fn serialize_tuple_variant_end(&mut self, state: EncoderState)
-> Result<(), Error> {
self.serialize_seq_end(state)
}
fn serialize_map(&mut self, _len: Option<usize>) -> Result<Self, Error> {
self.table_begin()
}
fn serialize_map_key<K>(&mut self,
_state: &mut Encoder,
key: K) -> Result<(), Error>
where K: ser::Serialize
{
self.table_key(|me| key.serialize(me))
}
fn serialize_map_value<V>(&mut self,
_state: &mut Encoder,
value: V) -> Result<(), Error>
where V: ser::Serialize
{
value.serialize(self)
}
fn serialize_map_end(&mut self, state: Self) -> Result<(), Error> {
self.table_end(state)
}
fn serialize_struct(&mut self,
_name: &'static str,
len: usize) -> Result<Self, Error> {
self.serialize_map(Some(len))
}
fn serialize_struct_elt<V>(&mut self,
state: &mut Encoder,
key: &'static str,
value: V) -> Result<(), Error>
where V: ser::Serialize
{
try!(self.serialize_map_key(state, key));
self.serialize_map_value(state, value)
}
fn serialize_struct_end(&mut self, state: Self) -> Result<(), Error> {
self.serialize_map_end(state)
}
fn serialize_struct_variant(&mut self,
_name: &'static str,
_id: usize,
_variant: &'static str,
len: usize) -> Result<Self, Error> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant_elt<V>(&mut self,
state: &mut Encoder,
key: &'static str,
value: V) -> Result<(), Error>
where V: ser::Serialize
{
try!(self.serialize_map_key(state, key));
self.serialize_map_value(state, value)
}
fn serialize_struct_variant_end(&mut self, state: Self) -> Result<(), Error> {
self.serialize_map_end(state)
}
fn serialize_newtype_struct<T>(&mut self,
_name: &'static str,
value: T) -> Result<(), Self::Error>
where T: ser::Serialize,
{
// Don't serialize the newtype struct in a tuple.
value.serialize(self)
}
fn serialize_newtype_variant<T>(&mut self,
_name: &'static str,
_variant_index: usize,
_variant: &'static str,
value: T) -> Result<(), Self::Error>
where T: ser::Serialize,
{
// Don't serialize the newtype struct variant in a tuple.
value.serialize(self)
}
fn serialize_unit_variant(&mut self,
_name: &'static str,
_variant_index: usize,
_variant: &'static str,
) -> Result<(), Self::Error>
{
Ok(())
}
}
impl ser::Serialize for Value {
fn serialize<E>(&self, e: &mut E) -> Result<(), E::Error>
where E: ser::Serializer
{
match *self {
Value::String(ref s) => e.serialize_str(s),
Value::Integer(i) => e.serialize_i64(i),
Value::Float(f) => e.serialize_f64(f),
Value::Boolean(b) => e.serialize_bool(b),
Value::Datetime(ref s) => e.serialize_str(s),
Value::Array(ref a) => {
let mut state = try!(e.serialize_seq(Some(a.len())));
for el in a.iter() {
try!(e.serialize_seq_elt(&mut state, el));
}
e.serialize_seq_end(state)
}
Value::Table(ref t) => {
let mut state = try!(e.serialize_map(Some(t.len())));
for (k, v) in t.iter() {
try!(e.serialize_map_key(&mut state, k));
try!(e.serialize_map_value(&mut state, v));
}
e.serialize_map_end(state)
}
}
}
}
impl ser::Error for Error {
fn custom<T: Into<String>>(msg: T) -> Error {
Error::Custom(msg.into())
}
}

630
third_party/rust/toml/src/lib.rs поставляемый
Просмотреть файл

@ -1,168 +1,492 @@
//! A [TOML]-parsing library
//! A TOML-parsing library
//!
//! This library implements a [TOML] v0.4.0 compatible parser,
//! primarily supporting the [`serde`] library for encoding/decoding
//! various types in Rust.
//! This library is an implementation in Rust of a parser for TOML configuration
//! files [1]. It is focused around high quality errors including specific spans
//! and detailed error messages when things go wrong.
//!
//! TOML itself is a simple, ergonomic, and readable configuration format:
//! This implementation currently passes the language agnostic [test suite][2].
//!
//! ```toml
//! [package]
//! name = "toml"
//! version = "0.4.2"
//! authors = ["Alex Crichton <alex@alexcrichton.com>"]
//! # Example
//!
//! [dependencies]
//! serde = "1.0"
//! ```
//! let toml = r#"
//! [test]
//! foo = "bar"
//! "#;
//!
//! let value = toml::Parser::new(toml).parse().unwrap();
//! println!("{:?}", value);
//! ```
//!
//! The TOML format tends to be relatively common throughout the Rust community
//! for configuration, notably being used by [Cargo], Rust's package manager.
//! # Conversions
//!
//! ## TOML values
//! This library also supports using the standard `Encodable` and `Decodable`
//! traits with TOML values. This library provides the following conversion
//! capabilities:
//!
//! A value in TOML is represented with the `Value` enum in this crate:
//! * `String` => `toml::Value` - via `Parser`
//! * `toml::Value` => `String` - via `Display`
//! * `toml::Value` => rust object - via `Decoder`
//! * rust object => `toml::Value` - via `Encoder`
//!
//! ```rust,ignore
//! pub enum Value {
//! String(String),
//! Integer(i64),
//! Float(f64),
//! Boolean(bool),
//! Datetime(Datetime),
//! Array(Array),
//! Table(Table),
//! }
//! ```
//! Convenience functions for performing multiple conversions at a time are also
//! provided.
//!
//! TOML is similar to JSON with the notable addition of a `Datetime`
//! type. In general, TOML and JSON are interchangeable in terms of
//! formats.
//!
//! ## Parsing TOML
//!
//! The easiest way to parse a TOML document is via the `Value` type:
//!
//! ```rust
//! use toml::Value;
//!
//! let value = "foo = 'bar'".parse::<Value>().unwrap();
//!
//! assert_eq!(value["foo"].as_str(), Some("bar"));
//! ```
//!
//! The `Value` type implements a number of convenience methods and
//! traits; the example above uses `FromStr` to parse a `str` into a
//! `Value`.
//!
//! ## Deserialization and Serialization
//!
//! This crate supports [`serde`] 1.0 with a number of
//! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
//! `Serializer` traits. Namely, you'll find:
//!
//! * `Deserialize for Value`
//! * `Serialize for Value`
//! * `Deserialize for Datetime`
//! * `Serialize for Datetime`
//! * `Deserializer for de::Deserializer`
//! * `Serializer for ser::Serializer`
//! * `Deserializer for Value`
//!
//! This means that you can use Serde to deserialize/serialize the
//! `Value` type as well as the `Datetime` type in this crate. You can also
//! use the `Deserializer`, `Serializer`, or `Value` type itself to act as
//! a deserializer/serializer for arbitrary types.
//!
//! An example of deserializing with TOML is:
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate toml;
//!
//! #[derive(Deserialize)]
//! struct Config {
//! ip: String,
//! port: Option<u16>,
//! keys: Keys,
//! }
//!
//! #[derive(Deserialize)]
//! struct Keys {
//! github: String,
//! travis: Option<String>,
//! }
//!
//! fn main() {
//! let config: Config = toml::from_str(r#"
//! ip = '127.0.0.1'
//!
//! [keys]
//! github = 'xxxxxxxxxxxxxxxxx'
//! travis = 'yyyyyyyyyyyyyyyyy'
//! "#).unwrap();
//!
//! assert_eq!(config.ip, "127.0.0.1");
//! assert_eq!(config.port, None);
//! assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx");
//! assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy");
//! }
//! ```
//!
//! You can serialize types in a similar fashion:
//!
//! ```rust
//! #[macro_use]
//! extern crate serde_derive;
//! extern crate toml;
//!
//! #[derive(Serialize)]
//! struct Config {
//! ip: String,
//! port: Option<u16>,
//! keys: Keys,
//! }
//!
//! #[derive(Serialize)]
//! struct Keys {
//! github: String,
//! travis: Option<String>,
//! }
//!
//! fn main() {
//! let config = Config {
//! ip: "127.0.0.1".to_string(),
//! port: None,
//! keys: Keys {
//! github: "xxxxxxxxxxxxxxxxx".to_string(),
//! travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
//! },
//! };
//!
//! let toml = toml::to_string(&config).unwrap();
//! }
//! ```
//!
//! [TOML]: https://github.com/toml-lang/toml
//! [Cargo]: https://crates.io/
//! [`serde`]: https://serde.rs/
//! [1]: https://github.com/mojombo/toml
//! [2]: https://github.com/BurntSushi/toml-test
#![doc(html_root_url = "https://docs.rs/toml/0.4")]
#![doc(html_root_url = "http://alexcrichton.com/toml-rs")]
#![deny(missing_docs)]
#![cfg_attr(test, deny(warnings))]
#[macro_use]
extern crate serde;
#[cfg(feature = "rustc-serialize")] extern crate rustc_serialize;
#[cfg(feature = "serde")] extern crate serde;
pub mod value;
#[doc(no_inline)]
pub use value::Value;
mod datetime;
use std::collections::BTreeMap;
use std::str::FromStr;
pub mod ser;
#[doc(no_inline)]
pub use ser::{to_string, to_string_pretty, to_vec, Serializer};
pub mod de;
#[doc(no_inline)]
pub use de::{from_slice, from_str, Deserializer};
mod tokens;
pub use parser::{Parser, ParserError};
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
pub use self::encoder::{Encoder, Error, EncoderState, encode, encode_str};
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
pub use self::decoder::{Decoder, DecodeError, DecodeErrorKind, decode, decode_str};
mod parser;
mod display;
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
mod encoder;
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
mod decoder;
/// Representation of a TOML value.
#[derive(PartialEq, Clone, Debug)]
#[allow(missing_docs)]
pub enum Value {
String(String),
Integer(i64),
Float(f64),
Boolean(bool),
Datetime(String),
Array(Array),
Table(Table),
}
/// Type representing a TOML array, payload of the `Value::Array` variant
pub type Array = Vec<Value>;
/// Type representing a TOML table, payload of the `Value::Table` variant
pub type Table = BTreeMap<String, Value>;
impl Value {
/// Tests whether this and another value have the same type.
pub fn same_type(&self, other: &Value) -> bool {
match (self, other) {
(&Value::String(..), &Value::String(..)) |
(&Value::Integer(..), &Value::Integer(..)) |
(&Value::Float(..), &Value::Float(..)) |
(&Value::Boolean(..), &Value::Boolean(..)) |
(&Value::Datetime(..), &Value::Datetime(..)) |
(&Value::Array(..), &Value::Array(..)) |
(&Value::Table(..), &Value::Table(..)) => true,
_ => false,
}
}
/// Returns a human-readable representation of the type of this value.
pub fn type_str(&self) -> &'static str {
match *self {
Value::String(..) => "string",
Value::Integer(..) => "integer",
Value::Float(..) => "float",
Value::Boolean(..) => "boolean",
Value::Datetime(..) => "datetime",
Value::Array(..) => "array",
Value::Table(..) => "table",
}
}
/// Extracts the string of this value if it is a string.
pub fn as_str(&self) -> Option<&str> {
match *self { Value::String(ref s) => Some(&**s), _ => None }
}
/// Extracts the integer value if it is an integer.
pub fn as_integer(&self) -> Option<i64> {
match *self { Value::Integer(i) => Some(i), _ => None }
}
/// Extracts the float value if it is a float.
pub fn as_float(&self) -> Option<f64> {
match *self { Value::Float(f) => Some(f), _ => None }
}
/// Extracts the boolean value if it is a boolean.
pub fn as_bool(&self) -> Option<bool> {
match *self { Value::Boolean(b) => Some(b), _ => None }
}
/// Extracts the datetime value if it is a datetime.
///
/// Note that a parsed TOML value will only contain ISO 8601 dates. An
/// example date is:
///
/// ```notrust
/// 1979-05-27T07:32:00Z
/// ```
pub fn as_datetime(&self) -> Option<&str> {
match *self { Value::Datetime(ref s) => Some(&**s), _ => None }
}
/// Extracts the array value if it is an array.
pub fn as_slice(&self) -> Option<&[Value]> {
match *self { Value::Array(ref s) => Some(&**s), _ => None }
}
/// Extracts the table value if it is a table.
pub fn as_table(&self) -> Option<&Table> {
match *self { Value::Table(ref s) => Some(s), _ => None }
}
/// Lookups for value at specified path.
///
/// Uses '.' as a path separator.
///
/// Note: arrays have zero-based indexes.
///
/// Note: empty path returns self.
///
/// ```
/// # #![allow(unstable)]
/// let toml = r#"
/// [test]
/// foo = "bar"
///
/// [[values]]
/// foo = "baz"
///
/// [[values]]
/// foo = "qux"
/// "#;
/// let value: toml::Value = toml.parse().unwrap();
///
/// let foo = value.lookup("test.foo").unwrap();
/// assert_eq!(foo.as_str().unwrap(), "bar");
///
/// let foo = value.lookup("values.1.foo").unwrap();
/// assert_eq!(foo.as_str().unwrap(), "qux");
///
/// let no_bar = value.lookup("test.bar");
/// assert_eq!(no_bar.is_none(), true);
/// ```
pub fn lookup(&self, path: &str) -> Option<&Value> {
let ref path = match Parser::new(path).lookup() {
Some(path) => path,
None => return None,
};
let mut cur_value = self;
if path.is_empty() {
return Some(cur_value)
}
for key in path {
match *cur_value {
Value::Table(ref hm) => {
match hm.get(key) {
Some(v) => cur_value = v,
None => return None
}
},
Value::Array(ref v) => {
match key.parse::<usize>().ok() {
Some(idx) if idx < v.len() => cur_value = &v[idx],
_ => return None
}
},
_ => return None
}
};
Some(cur_value)
}
/// Lookups for mutable value at specified path.
///
/// Uses '.' as a path separator.
///
/// Note: arrays have zero-based indexes.
///
/// Note: empty path returns self.
///
/// ```
/// # #![allow(unstable)]
/// let toml = r#"
/// [test]
/// foo = "bar"
///
/// [[values]]
/// foo = "baz"
///
/// [[values]]
/// foo = "qux"
/// "#;
/// let mut value: toml::Value = toml.parse().unwrap();
/// {
/// let string = value.lookup_mut("test.foo").unwrap();
/// assert_eq!(string, &mut toml::Value::String(String::from("bar")));
/// *string = toml::Value::String(String::from("foo"));
/// }
/// let result = value.lookup_mut("test.foo").unwrap();
/// assert_eq!(result.as_str().unwrap(), "foo");
/// ```
pub fn lookup_mut(&mut self, path: &str) -> Option<&mut Value> {
let ref path = match Parser::new(path).lookup() {
Some(path) => path,
None => return None,
};
let mut cur = self;
if path.is_empty() {
return Some(cur)
}
for key in path {
let tmp = cur;
match *tmp {
Value::Table(ref mut hm) => {
match hm.get_mut(key) {
Some(v) => cur = v,
None => return None
}
}
Value::Array(ref mut v) => {
match key.parse::<usize>().ok() {
Some(idx) if idx < v.len() => cur = &mut v[idx],
_ => return None
}
}
_ => return None
}
}
Some(cur)
}
}
impl FromStr for Value {
type Err = Vec<ParserError>;
fn from_str(s: &str) -> Result<Value, Vec<ParserError>> {
let mut p = Parser::new(s);
match p.parse().map(Value::Table) {
Some(n) => Ok(n),
None => Err(p.errors),
}
}
}
#[cfg(test)]
mod tests {
use super::Value;
#[test]
fn lookup_mut_change() {
let toml = r#"
[test]
foo = "bar"
[[values]]
foo = "baz"
[[values]]
foo = "qux"
"#;
let mut value: Value = toml.parse().unwrap();
{
let foo = value.lookup_mut("values.0.foo").unwrap();
*foo = Value::String(String::from("bar"));
}
let foo = value.lookup("values.0.foo").unwrap();
assert_eq!(foo.as_str().unwrap(), "bar");
}
#[test]
fn lookup_mut_valid() {
let toml = r#"
[test]
foo = "bar"
[[values]]
foo = "baz"
[[values]]
foo = "qux"
"#;
let mut value: Value = toml.parse().unwrap();
{
let test_foo = value.lookup_mut("test.foo").unwrap();
assert_eq!(test_foo.as_str().unwrap(), "bar");
}
{
let foo1 = value.lookup_mut("values.1.foo").unwrap();
assert_eq!(foo1.as_str().unwrap(), "qux");
}
assert!(value.lookup_mut("test.bar").is_none());
assert!(value.lookup_mut("test.foo.bar").is_none());
}
#[test]
fn lookup_mut_invalid_index() {
let toml = r#"
[[values]]
foo = "baz"
"#;
let mut value: Value = toml.parse().unwrap();
{
let foo = value.lookup_mut("test.foo");
assert!(foo.is_none());
}
{
let foo = value.lookup_mut("values.100.foo");
assert!(foo.is_none());
}
{
let foo = value.lookup_mut("values.str.foo");
assert!(foo.is_none());
}
}
#[test]
fn lookup_mut_self() {
let mut value: Value = r#"foo = "bar""#.parse().unwrap();
{
let foo = value.lookup_mut("foo").unwrap();
assert_eq!(foo.as_str().unwrap(), "bar");
}
let foo = value.lookup_mut("").unwrap();
assert!(foo.as_table().is_some());
let baz = foo.lookup_mut("foo").unwrap();
assert_eq!(baz.as_str().unwrap(), "bar");
}
#[test]
fn lookup_valid() {
let toml = r#"
[test]
foo = "bar"
[[values]]
foo = "baz"
[[values]]
foo = "qux"
"#;
let value: Value = toml.parse().unwrap();
let test_foo = value.lookup("test.foo").unwrap();
assert_eq!(test_foo.as_str().unwrap(), "bar");
let foo1 = value.lookup("values.1.foo").unwrap();
assert_eq!(foo1.as_str().unwrap(), "qux");
assert!(value.lookup("test.bar").is_none());
assert!(value.lookup("test.foo.bar").is_none());
}
#[test]
fn lookup_invalid_index() {
let toml = r#"
[[values]]
foo = "baz"
"#;
let value: Value = toml.parse().unwrap();
let foo = value.lookup("test.foo");
assert!(foo.is_none());
let foo = value.lookup("values.100.foo");
assert!(foo.is_none());
let foo = value.lookup("values.str.foo");
assert!(foo.is_none());
}
#[test]
fn lookup_self() {
let value: Value = r#"foo = "bar""#.parse().unwrap();
let foo = value.lookup("foo").unwrap();
assert_eq!(foo.as_str().unwrap(), "bar");
let foo = value.lookup("").unwrap();
assert!(foo.as_table().is_some());
let baz = foo.lookup("foo").unwrap();
assert_eq!(baz.as_str().unwrap(), "bar");
}
#[test]
fn lookup_advanced() {
let value: Value = "[table]\n\"value\" = 0".parse().unwrap();
let looked = value.lookup("table.\"value\"").unwrap();
assert_eq!(*looked, Value::Integer(0));
}
#[test]
fn lookup_advanced_table() {
let value: Value = "[table.\"name.other\"]\nvalue = \"my value\"".parse().unwrap();
let looked = value.lookup(r#"table."name.other".value"#).unwrap();
assert_eq!(*looked, Value::String(String::from("my value")));
}
#[test]
fn lookup_mut_advanced() {
let mut value: Value = "[table]\n\"value\" = [0, 1, 2]".parse().unwrap();
let looked = value.lookup_mut("table.\"value\".1").unwrap();
assert_eq!(*looked, Value::Integer(1));
}
#[test]
fn single_dot() {
let value: Value = "[table]\n\"value\" = [0, 1, 2]".parse().unwrap();
assert_eq!(None, value.lookup("."));
}
#[test]
fn array_dot() {
let value: Value = "[table]\n\"value\" = [0, 1, 2]".parse().unwrap();
assert_eq!(None, value.lookup("0."));
}
#[test]
fn dot_inside() {
let value: Value = "[table]\n\"value\" = [0, 1, 2]".parse().unwrap();
assert_eq!(None, value.lookup("table.\"value.0\""));
}
#[test]
fn table_with_quotes() {
let value: Value = "[table.\"element\"]\n\"value\" = [0, 1, 2]".parse().unwrap();
assert_eq!(None, value.lookup("\"table.element\".\"value\".0"));
}
#[test]
fn table_with_quotes_2() {
let value: Value = "[table.\"element\"]\n\"value\" = [0, 1, 2]".parse().unwrap();
assert_eq!(Value::Integer(0), *value.lookup("table.\"element\".\"value\".0").unwrap());
}
}

1627
third_party/rust/toml/src/parser.rs поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

1714
third_party/rust/toml/src/ser.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

620
third_party/rust/toml/src/tokens.rs поставляемый
Просмотреть файл

@ -1,620 +0,0 @@
use std::borrow::Cow;
use std::char;
use std::str;
use std::string;
use self::Token::*;
#[derive(Eq, PartialEq, Debug)]
pub enum Token<'a> {
Whitespace(&'a str),
Newline,
Comment(&'a str),
Equals,
Period,
Comma,
Colon,
Plus,
LeftBrace,
RightBrace,
LeftBracket,
RightBracket,
Keylike(&'a str),
String { src: &'a str, val: Cow<'a, str> },
}
#[derive(Eq, PartialEq, Debug)]
pub enum Error {
InvalidCharInString(usize, char),
InvalidEscape(usize, char),
InvalidHexEscape(usize, char),
InvalidEscapeValue(usize, u32),
NewlineInString(usize),
Unexpected(usize, char),
UnterminatedString(usize),
NewlineInTableKey(usize),
EmptyTableKey(usize),
Wanted { at: usize, expected: &'static str, found: &'static str },
}
#[derive(Clone)]
pub struct Tokenizer<'a> {
input: &'a str,
chars: CrlfFold<'a>,
}
#[derive(Clone)]
struct CrlfFold<'a> {
chars: str::CharIndices<'a>,
}
#[derive(Debug)]
enum MaybeString {
NotEscaped(usize),
Owned(string::String),
}
impl<'a> Tokenizer<'a> {
pub fn new(input: &'a str) -> Tokenizer<'a> {
let mut t = Tokenizer {
input: input,
chars: CrlfFold {
chars: input.char_indices(),
},
};
// Eat utf-8 BOM
t.eatc('\u{feff}');
t
}
pub fn next(&mut self) -> Result<Option<Token<'a>>, Error> {
let token = match self.chars.next() {
Some((_, '\n')) => Newline,
Some((start, ' ')) => self.whitespace_token(start),
Some((start, '\t')) => self.whitespace_token(start),
Some((start, '#')) => self.comment_token(start),
Some((_, '=')) => Equals,
Some((_, '.')) => Period,
Some((_, ',')) => Comma,
Some((_, ':')) => Colon,
Some((_, '+')) => Plus,
Some((_, '{')) => LeftBrace,
Some((_, '}')) => RightBrace,
Some((_, '[')) => LeftBracket,
Some((_, ']')) => RightBracket,
Some((start, '\'')) => return self.literal_string(start).map(Some),
Some((start, '"')) => return self.basic_string(start).map(Some),
Some((start, ch)) if is_keylike(ch) => self.keylike(start),
Some((start, ch)) => return Err(Error::Unexpected(start, ch)),
None => return Ok(None),
};
Ok(Some(token))
}
pub fn peek(&mut self) -> Result<Option<Token<'a>>, Error> {
self.clone().next()
}
pub fn eat(&mut self, expected: Token<'a>) -> Result<bool, Error> {
match self.peek()? {
Some(ref found) if expected == *found => {}
Some(_) => return Ok(false),
None => return Ok(false),
}
drop(self.next());
Ok(true)
}
pub fn expect(&mut self, expected: Token<'a>) -> Result<(), Error> {
let current = self.current();
match self.next()? {
Some(found) => {
if expected == found {
Ok(())
} else {
Err(Error::Wanted {
at: current,
expected: expected.describe(),
found: found.describe(),
})
}
}
None => {
Err(Error::Wanted {
at: self.input.len(),
expected: expected.describe(),
found: "eof",
})
}
}
}
pub fn table_key(&mut self) -> Result<Cow<'a, str>, Error> {
let current = self.current();
match self.next()? {
Some(Token::Keylike(k)) => Ok(k.into()),
Some(Token::String { src, val }) => {
let offset = self.substr_offset(src);
if val == "" {
return Err(Error::EmptyTableKey(offset))
}
match src.find('\n') {
None => Ok(val),
Some(i) => Err(Error::NewlineInTableKey(offset + i)),
}
}
Some(other) => {
Err(Error::Wanted {
at: current,
expected: "a table key",
found: other.describe(),
})
}
None => {
Err(Error::Wanted {
at: self.input.len(),
expected: "a table key",
found: "eof",
})
}
}
}
pub fn eat_whitespace(&mut self) -> Result<(), Error> {
while self.eatc(' ') || self.eatc('\t') {
// ...
}
Ok(())
}
pub fn eat_comment(&mut self) -> Result<bool, Error> {
if !self.eatc('#') {
return Ok(false)
}
drop(self.comment_token(0));
self.eat_newline_or_eof().map(|()| true)
}
pub fn eat_newline_or_eof(&mut self) -> Result<(), Error> {
let current = self.current();
match self.next()? {
None |
Some(Token::Newline) => Ok(()),
Some(other) => {
Err(Error::Wanted {
at: current,
expected: "newline",
found: other.describe(),
})
}
}
}
pub fn skip_to_newline(&mut self) {
loop {
match self.chars.next() {
Some((_, '\n')) |
None => break,
_ => {}
}
}
}
fn eatc(&mut self, ch: char) -> bool {
match self.chars.clone().next() {
Some((_, ch2)) if ch == ch2 => {
self.chars.next();
true
}
_ => false,
}
}
pub fn current(&mut self) -> usize {
self.chars.clone().next().map(|i| i.0).unwrap_or(self.input.len())
}
pub fn input(&self) -> &'a str {
self.input
}
fn whitespace_token(&mut self, start: usize) -> Token<'a> {
while self.eatc(' ') || self.eatc('\t') {
// ...
}
Whitespace(&self.input[start..self.current()])
}
fn comment_token(&mut self, start: usize) -> Token<'a> {
while let Some((_, ch)) = self.chars.clone().next() {
if ch != '\t' && (ch < '\u{20}' || ch > '\u{10ffff}') {
break
}
self.chars.next();
}
Comment(&self.input[start..self.current()])
}
fn read_string(&mut self,
delim: char,
start: usize,
new_ch: &mut FnMut(&mut Tokenizer, &mut MaybeString,
bool, usize, char)
-> Result<(), Error>)
-> Result<Token<'a>, Error> {
let mut multiline = false;
if self.eatc(delim) {
if self.eatc(delim) {
multiline = true;
} else {
return Ok(String {
src: &self.input[start..start+2],
val: Cow::Borrowed(""),
})
}
}
let mut val = MaybeString::NotEscaped(self.current());
let mut n = 0;
'outer: loop {
n += 1;
match self.chars.next() {
Some((i, '\n')) => {
if multiline {
if self.input.as_bytes()[i] == b'\r' {
val.to_owned(&self.input[..i]);
}
if n == 1 {
val = MaybeString::NotEscaped(self.current());
} else {
val.push('\n');
}
continue
} else {
return Err(Error::NewlineInString(i))
}
}
Some((i, ch)) if ch == delim => {
if multiline {
for _ in 0..2 {
if !self.eatc(delim) {
val.push(delim);
continue 'outer
}
}
}
return Ok(String {
src: &self.input[start..self.current()],
val: val.into_cow(&self.input[..i]),
})
}
Some((i, c)) => try!(new_ch(self, &mut val, multiline, i, c)),
None => return Err(Error::UnterminatedString(start))
}
}
}
fn literal_string(&mut self, start: usize) -> Result<Token<'a>, Error> {
self.read_string('\'', start, &mut |_me, val, _multi, i, ch| {
if ch == '\u{09}' || ('\u{20}' <= ch && ch <= '\u{10ffff}') {
val.push(ch);
Ok(())
} else {
Err(Error::InvalidCharInString(i, ch))
}
})
}
fn basic_string(&mut self, start: usize) -> Result<Token<'a>, Error> {
self.read_string('"', start, &mut |me, val, multi, i, ch| {
match ch {
'\\' => {
val.to_owned(&me.input[..i]);
match me.chars.next() {
Some((_, '"')) => val.push('"'),
Some((_, '\\')) => val.push('\\'),
Some((_, 'b')) => val.push('\u{8}'),
Some((_, 'f')) => val.push('\u{c}'),
Some((_, 'n')) => val.push('\n'),
Some((_, 'r')) => val.push('\r'),
Some((_, 't')) => val.push('\t'),
Some((i, c @ 'u')) |
Some((i, c @ 'U')) => {
let len = if c == 'u' {4} else {8};
val.push(try!(me.hex(start, i, len)));
}
Some((_, '\n')) if multi => {
while let Some((_, ch)) = me.chars.clone().next() {
match ch {
' ' | '\t' | '\n' => {
me.chars.next();
}
_ => break,
}
}
}
Some((i, c)) => return Err(Error::InvalidEscape(i, c)),
None => return Err(Error::UnterminatedString(start)),
}
Ok(())
}
ch if '\u{20}' <= ch && ch <= '\u{10ffff}' => {
val.push(ch);
Ok(())
}
_ => Err(Error::InvalidCharInString(i, ch))
}
})
}
fn hex(&mut self, start: usize, i: usize, len: usize) -> Result<char, Error> {
let mut val = 0;
for _ in 0..len {
match self.chars.next() {
Some((_, ch)) if '0' <= ch && ch <= '9' => {
val = val * 16 + (ch as u32 - '0' as u32);
}
Some((_, ch)) if 'A' <= ch && ch <= 'F' => {
val = val * 16 + (ch as u32 - 'A' as u32) + 10;
}
Some((i, ch)) => return Err(Error::InvalidHexEscape(i, ch)),
None => return Err(Error::UnterminatedString(start)),
}
}
match char::from_u32(val) {
Some(ch) => Ok(ch),
None => Err(Error::InvalidEscapeValue(i, val)),
}
}
fn keylike(&mut self, start: usize) -> Token<'a> {
while let Some((_, ch)) = self.chars.clone().next() {
if !is_keylike(ch) {
break
}
self.chars.next();
}
Keylike(&self.input[start..self.current()])
}
pub fn substr_offset(&self, s: &'a str) -> usize {
assert!(s.len() <= self.input.len());
let a = self.input.as_ptr() as usize;
let b = s.as_ptr() as usize;
assert!(a <= b);
b - a
}
}
impl<'a> Iterator for CrlfFold<'a> {
type Item = (usize, char);
fn next(&mut self) -> Option<(usize, char)> {
self.chars.next().map(|(i, c)| {
if c == '\r' {
let mut attempt = self.chars.clone();
if let Some((_, '\n')) = attempt.next() {
self.chars = attempt;
return (i, '\n')
}
}
(i, c)
})
}
}
impl MaybeString {
fn push(&mut self, ch: char) {
match *self {
MaybeString::NotEscaped(..) => {}
MaybeString::Owned(ref mut s) => s.push(ch),
}
}
fn to_owned(&mut self, input: &str) {
match *self {
MaybeString::NotEscaped(start) => {
*self = MaybeString::Owned(input[start..].to_owned());
}
MaybeString::Owned(..) => {}
}
}
fn into_cow(self, input: &str) -> Cow<str> {
match self {
MaybeString::NotEscaped(start) => Cow::Borrowed(&input[start..]),
MaybeString::Owned(s) => Cow::Owned(s),
}
}
}
fn is_keylike(ch: char) -> bool {
('A' <= ch && ch <= 'Z') ||
('a' <= ch && ch <= 'z') ||
('0' <= ch && ch <= '9') ||
ch == '-' ||
ch == '_'
}
impl<'a> Token<'a> {
pub fn describe(&self) -> &'static str {
match *self {
Token::Keylike(_) => "an identifier",
Token::Equals => "an equals",
Token::Period => "a period",
Token::Comment(_) => "a comment",
Token::Newline => "a newline",
Token::Whitespace(_) => "whitespace",
Token::Comma => "a comma",
Token::RightBrace => "a right brace",
Token::LeftBrace => "a left brace",
Token::RightBracket => "a right bracket",
Token::LeftBracket => "a left bracket",
Token::String { .. } => "a string",
Token::Colon => "a colon",
Token::Plus => "a plus",
}
}
}
#[cfg(test)]
mod tests {
use std::borrow::Cow;
use super::{Tokenizer, Token, Error};
fn err(input: &str, err: Error) {
let mut t = Tokenizer::new(input);
let token = t.next().unwrap_err();
assert_eq!(token, err);
assert!(t.next().unwrap().is_none());
}
#[test]
fn literal_strings() {
fn t(input: &str, val: &str) {
let mut t = Tokenizer::new(input);
let token = t.next().unwrap().unwrap();
assert_eq!(token, Token::String {
src: input,
val: Cow::Borrowed(val),
});
assert!(t.next().unwrap().is_none());
}
t("''", "");
t("''''''", "");
t("'''\n'''", "");
t("'a'", "a");
t("'\"a'", "\"a");
t("''''a'''", "'a");
t("'''\n'a\n'''", "'a\n");
t("'''a\n'a\r\n'''", "a\n'a\n");
}
#[test]
fn basic_strings() {
fn t(input: &str, val: &str) {
let mut t = Tokenizer::new(input);
let token = t.next().unwrap().unwrap();
assert_eq!(token, Token::String {
src: input,
val: Cow::Borrowed(val),
});
assert!(t.next().unwrap().is_none());
}
t(r#""""#, "");
t(r#""""""""#, "");
t(r#""a""#, "a");
t(r#""""a""""#, "a");
t(r#""\t""#, "\t");
t(r#""\u0000""#, "\0");
t(r#""\U00000000""#, "\0");
t(r#""\U000A0000""#, "\u{A0000}");
t(r#""\\t""#, "\\t");
t("\"\"\"\\\n\"\"\"", "");
t("\"\"\"\\\n \t \t \\\r\n \t \n \t \r\n\"\"\"", "");
t(r#""\r""#, "\r");
t(r#""\n""#, "\n");
t(r#""\b""#, "\u{8}");
t(r#""a\fa""#, "a\u{c}a");
t(r#""\"a""#, "\"a");
t("\"\"\"\na\"\"\"", "a");
t("\"\"\"\n\"\"\"", "");
err(r#""\a"#, Error::InvalidEscape(2, 'a'));
err("\"\\\n", Error::InvalidEscape(2, '\n'));
err("\"\\\r\n", Error::InvalidEscape(2, '\n'));
err("\"\\", Error::UnterminatedString(0));
err("\"\u{0}", Error::InvalidCharInString(1, '\u{0}'));
err(r#""\U00""#, Error::InvalidHexEscape(5, '"'));
err(r#""\U00"#, Error::UnterminatedString(0));
err(r#""\uD800"#, Error::InvalidEscapeValue(2, 0xd800));
err(r#""\UFFFFFFFF"#, Error::InvalidEscapeValue(2, 0xffffffff));
}
#[test]
fn keylike() {
fn t(input: &str) {
let mut t = Tokenizer::new(input);
let token = t.next().unwrap().unwrap();
assert_eq!(token, Token::Keylike(input));
assert!(t.next().unwrap().is_none());
}
t("foo");
t("0bar");
t("bar0");
t("1234");
t("a-b");
t("a_B");
t("-_-");
t("___");
}
#[test]
fn all() {
fn t(input: &str, expected: &[Token]) {
let mut tokens = Tokenizer::new(input);
let mut actual = Vec::new();
while let Some(token) = tokens.next().unwrap() {
actual.push(token);
}
for (a, b) in actual.iter().zip(expected) {
assert_eq!(a, b);
}
assert_eq!(actual.len(), expected.len());
}
t(" a ", &[
Token::Whitespace(" "),
Token::Keylike("a"),
Token::Whitespace(" "),
]);
t(" a\t [[]] \t [] {} , . =\n# foo \r\n#foo \n ", &[
Token::Whitespace(" "),
Token::Keylike("a"),
Token::Whitespace("\t "),
Token::LeftBracket,
Token::LeftBracket,
Token::RightBracket,
Token::RightBracket,
Token::Whitespace(" \t "),
Token::LeftBracket,
Token::RightBracket,
Token::Whitespace(" "),
Token::LeftBrace,
Token::RightBrace,
Token::Whitespace(" "),
Token::Comma,
Token::Whitespace(" "),
Token::Period,
Token::Whitespace(" "),
Token::Equals,
Token::Newline,
Token::Comment("# foo "),
Token::Newline,
Token::Comment("#foo "),
Token::Newline,
Token::Whitespace(" "),
]);
}
#[test]
fn bare_cr_bad() {
err("\r", Error::Unexpected(0, '\r'));
err("'\n", Error::NewlineInString(1));
err("'\u{0}", Error::InvalidCharInString(1, '\u{0}'));
err("'", Error::UnterminatedString(0));
err("\u{0}", Error::Unexpected(0, '\u{0}'));
}
#[test]
fn bad_comment() {
let mut t = Tokenizer::new("#\u{0}");
t.next().unwrap().unwrap();
assert_eq!(t.next(), Err(Error::Unexpected(1, '\u{0}')));
assert!(t.next().unwrap().is_none());
}
}

946
third_party/rust/toml/src/value.rs поставляемый
Просмотреть файл

@ -1,946 +0,0 @@
//! Definition of a TOML value
use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
use std::fmt;
use std::ops;
use std::str::FromStr;
use std::vec;
use serde::ser;
use serde::de;
use serde::de::IntoDeserializer;
pub use datetime::{Datetime, DatetimeParseError};
use datetime::{DatetimeFromString, SERDE_STRUCT_FIELD_NAME};
/// Representation of a TOML value.
#[derive(PartialEq, Clone, Debug)]
pub enum Value {
/// Represents a TOML string
String(String),
/// Represents a TOML integer
Integer(i64),
/// Represents a TOML float
Float(f64),
/// Represents a TOML boolean
Boolean(bool),
/// Represents a TOML datetime
Datetime(Datetime),
/// Represents a TOML array
Array(Array),
/// Represents a TOML table
Table(Table),
}
/// Type representing a TOML array, payload of the `Value::Array` variant
pub type Array = Vec<Value>;
/// Type representing a TOML table, payload of the `Value::Table` variant
pub type Table = BTreeMap<String, Value>;
impl Value {
/// Convert a `T` into `toml::Value` which is an enum that can represent
/// any valid TOML data.
///
/// This conversion can fail if `T`'s implementation of `Serialize` decides to
/// fail, or if `T` contains a map with non-string keys.
pub fn try_from<T>(value: T) -> Result<Value, ::ser::Error>
where T: ser::Serialize,
{
value.serialize(Serializer)
}
/// Interpret a `toml::Value` as an instance of type `T`.
///
/// This conversion can fail if the structure of the `Value` does not match the
/// structure expected by `T`, for example if `T` is a struct type but the
/// `Value` contains something other than a TOML table. It can also fail if the
/// structure is correct but `T`'s implementation of `Deserialize` decides that
/// 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
/// primitive type.
pub fn try_into<'de, T>(self) -> Result<T, ::de::Error>
where T: de::Deserialize<'de>,
{
de::Deserialize::deserialize(self)
}
/// Index into a TOML array or map. A string index can be used to access a
/// value in a map, and a usize index can be used to access an element of an
/// array.
///
/// Returns `None` if the type of `self` does not match the type of the
/// index, for example if the index is a string and `self` is an array or a
/// number. Also returns `None` if the given key does not exist in the map
/// or the given index is not within the bounds of the array.
pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
index.index(self)
}
/// Mutably index into a TOML array or map. A string index can be used to
/// access a value in a map, and a usize index can be used to access an
/// element of an array.
///
/// Returns `None` if the type of `self` does not match the type of the
/// index, for example if the index is a string and `self` is an array or a
/// number. Also returns `None` if the given key does not exist in the map
/// or the given index is not within the bounds of the array.
pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
index.index_mut(self)
}
/// Extracts the integer value if it is an integer.
pub fn as_integer(&self) -> Option<i64> {
match *self { Value::Integer(i) => Some(i), _ => None }
}
/// Tests whether this value is an integer
pub fn is_integer(&self) -> bool {
self.as_integer().is_some()
}
/// Extracts the float value if it is a float.
pub fn as_float(&self) -> Option<f64> {
match *self { Value::Float(f) => Some(f), _ => None }
}
/// Tests whether this value is a float
pub fn is_float(&self) -> bool {
self.as_float().is_some()
}
/// Extracts the boolean value if it is a boolean.
pub fn as_bool(&self) -> Option<bool> {
match *self { Value::Boolean(b) => Some(b), _ => None }
}
/// Tests whether this value is a boolean
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
/// Extracts the string of this value if it is a string.
pub fn as_str(&self) -> Option<&str> {
match *self { Value::String(ref s) => Some(&**s), _ => None }
}
/// Tests if this value is a string
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
/// Extracts the datetime value if it is a datetime.
///
/// Note that a parsed TOML value will only contain ISO 8601 dates. An
/// example date is:
///
/// ```notrust
/// 1979-05-27T07:32:00Z
/// ```
pub fn as_datetime(&self) -> Option<&Datetime> {
match *self { Value::Datetime(ref s) => Some(s), _ => None }
}
/// Tests whether this value is a datetime
pub fn is_datetime(&self) -> bool {
self.as_datetime().is_some()
}
/// Extracts the array value if it is an array.
pub fn as_array(&self) -> Option<&Vec<Value>> {
match *self { Value::Array(ref s) => Some(s), _ => None }
}
/// Extracts the array value if it is an array.
pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
match *self { Value::Array(ref mut s) => Some(s), _ => None }
}
/// Tests whether this value is an array
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
/// Extracts the table value if it is a table.
pub fn as_table(&self) -> Option<&Table> {
match *self { Value::Table(ref s) => Some(s), _ => None }
}
/// Extracts the table value if it is a table.
pub fn as_table_mut(&mut self) -> Option<&mut Table> {
match *self { Value::Table(ref mut s) => Some(s), _ => None }
}
/// Extracts the table value if it is a table.
pub fn is_table(&self) -> bool {
self.as_table().is_some()
}
/// Tests whether this and another value have the same type.
pub fn same_type(&self, other: &Value) -> bool {
match (self, other) {
(&Value::String(..), &Value::String(..)) |
(&Value::Integer(..), &Value::Integer(..)) |
(&Value::Float(..), &Value::Float(..)) |
(&Value::Boolean(..), &Value::Boolean(..)) |
(&Value::Datetime(..), &Value::Datetime(..)) |
(&Value::Array(..), &Value::Array(..)) |
(&Value::Table(..), &Value::Table(..)) => true,
_ => false,
}
}
/// Returns a human-readable representation of the type of this value.
pub fn type_str(&self) -> &'static str {
match *self {
Value::String(..) => "string",
Value::Integer(..) => "integer",
Value::Float(..) => "float",
Value::Boolean(..) => "boolean",
Value::Datetime(..) => "datetime",
Value::Array(..) => "array",
Value::Table(..) => "table",
}
}
}
impl<I> ops::Index<I> for Value where I: Index {
type Output = Value;
fn index(&self, index: I) -> &Value {
self.get(index).expect("index not found")
}
}
impl<I> ops::IndexMut<I> for Value where I: Index {
fn index_mut(&mut self, index: I) -> &mut Value {
self.get_mut(index).expect("index not found")
}
}
impl<'a> From<&'a str> for Value {
#[inline]
fn from(val: &'a str) -> Value {
Value::String(val.to_string())
}
}
impl<V: Into<Value>> From<Vec<V>> for Value {
fn from(val: Vec<V>) -> Value {
Value::Array(val.into_iter().map(|v| v.into()).collect())
}
}
impl<S: Into<String>, V: Into<Value>> From<BTreeMap<S, V>> for Value {
fn from(val: BTreeMap<S, V>) -> Value {
let table = val.into_iter()
.map(|(s, v)| (s.into(), v.into()))
.collect();
Value::Table(table)
}
}
impl<S: Into<String> + Hash + Eq, V: Into<Value>> From<HashMap<S, V>> for Value {
fn from(val: HashMap<S, V>) -> Value {
let table = val.into_iter()
.map(|(s, v)| (s.into(), v.into()))
.collect();
Value::Table(table)
}
}
macro_rules! impl_into_value {
($variant:ident : $T:ty) => {
impl From<$T> for Value {
#[inline]
fn from(val: $T) -> Value {
Value::$variant(val.into())
}
}
}
}
impl_into_value!(String: String);
impl_into_value!(Integer: i64);
impl_into_value!(Integer: i32);
impl_into_value!(Integer: i8);
impl_into_value!(Integer: u8);
impl_into_value!(Integer: u32);
impl_into_value!(Float: f64);
impl_into_value!(Float: f32);
impl_into_value!(Boolean: bool);
impl_into_value!(Datetime: Datetime);
/// Types that can be used to index a `toml::Value`
///
/// Currently this is implemented for `usize` to index arrays and `str` to index
/// tables.
///
/// This trait is sealed and not intended for implementation outside of the
/// `toml` crate.
pub trait Index: Sealed {
#[doc(hidden)]
fn index<'a>(&self, val: &'a Value) -> Option<&'a Value>;
#[doc(hidden)]
fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value>;
}
/// An implementation detail that should not be implemented, this will change in
/// the future and break code otherwise.
#[doc(hidden)]
pub trait Sealed {}
impl Sealed for usize {}
impl Sealed for str {}
impl Sealed for String {}
impl<'a, T: Sealed + ?Sized> Sealed for &'a T {}
impl Index for usize {
fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> {
match *val {
Value::Array(ref a) => a.get(*self),
_ => None,
}
}
fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> {
match *val {
Value::Array(ref mut a) => a.get_mut(*self),
_ => None,
}
}
}
impl Index for str {
fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> {
match *val {
Value::Table(ref a) => a.get(self),
_ => None,
}
}
fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> {
match *val {
Value::Table(ref mut a) => a.get_mut(self),
_ => None,
}
}
}
impl Index for String {
fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> {
self[..].index(val)
}
fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> {
self[..].index_mut(val)
}
}
impl<'s, T: ?Sized> Index for &'s T where T: Index {
fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> {
(**self).index(val)
}
fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> {
(**self).index_mut(val)
}
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
::ser::to_string(self).expect("Unable to represent value as string").fmt(f)
}
}
impl FromStr for Value {
type Err = ::de::Error;
fn from_str(s: &str) -> Result<Value, Self::Err> {
::from_str(s)
}
}
impl ser::Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: ser::Serializer
{
use serde::ser::SerializeMap;
match *self {
Value::String(ref s) => serializer.serialize_str(s),
Value::Integer(i) => serializer.serialize_i64(i),
Value::Float(f) => serializer.serialize_f64(f),
Value::Boolean(b) => serializer.serialize_bool(b),
Value::Datetime(ref s) => s.serialize(serializer),
Value::Array(ref a) => a.serialize(serializer),
Value::Table(ref t) => {
let mut map = serializer.serialize_map(Some(t.len()))?;
// Be sure to visit non-tables first (and also non
// array-of-tables) as all keys must be emitted first.
for (k, v) in t {
if !v.is_table() && !v.is_array() ||
(v.as_array().map(|a| !a.iter().any(|v| v.is_table())).unwrap_or(false)) {
map.serialize_entry(k, v)?;
}
}
for (k, v) in t {
if v.as_array().map(|a| a.iter().any(|v| v.is_table())).unwrap_or(false) {
map.serialize_entry(k, v)?;
}
}
for (k, v) in t {
if v.is_table() {
map.serialize_entry(k, v)?;
}
}
map.end()
}
}
}
}
impl<'de> de::Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
where D: de::Deserializer<'de>,
{
struct ValueVisitor;
impl<'de> de::Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("any valid TOML value")
}
fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
Ok(Value::Boolean(value))
}
fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
Ok(Value::Integer(value))
}
fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
Ok(Value::Float(value))
}
fn visit_str<E>(self, value: &str) -> Result<Value, E> {
Ok(Value::String(value.into()))
}
fn visit_string<E>(self, value: String) -> Result<Value, E> {
Ok(Value::String(value))
}
fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
where D: de::Deserializer<'de>,
{
de::Deserialize::deserialize(deserializer)
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
where V: de::SeqAccess<'de>,
{
let mut vec = Vec::new();
while let Some(elem) = try!(visitor.next_element()) {
vec.push(elem);
}
Ok(Value::Array(vec))
}
fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
where V: de::MapAccess<'de>,
{
let mut key = String::new();
let datetime = visitor.next_key_seed(DatetimeOrTable {
key: &mut key,
})?;
match datetime {
Some(true) => {
let date: DatetimeFromString = visitor.next_value()?;
return Ok(Value::Datetime(date.value))
}
None => return Ok(Value::Table(BTreeMap::new())),
Some(false) => {}
}
let mut map = BTreeMap::new();
map.insert(key, visitor.next_value()?);
while let Some(key) = visitor.next_key()? {
if map.contains_key(&key) {
let msg = format!("duplicate key: `{}`", key);
return Err(de::Error::custom(msg))
}
map.insert(key, visitor.next_value()?);
}
Ok(Value::Table(map))
}
}
deserializer.deserialize_any(ValueVisitor)
}
}
impl<'de> de::Deserializer<'de> for Value {
type Error = ::de::Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, ::de::Error>
where V: de::Visitor<'de>,
{
match self {
Value::Boolean(v) => visitor.visit_bool(v),
Value::Integer(n) => visitor.visit_i64(n),
Value::Float(n) => visitor.visit_f64(n),
Value::String(v) => visitor.visit_string(v),
Value::Datetime(v) => visitor.visit_string(v.to_string()),
Value::Array(v) => {
let len = v.len();
let mut deserializer = SeqDeserializer::new(v);
let seq = visitor.visit_seq(&mut deserializer)?;
let remaining = deserializer.iter.len();
if remaining == 0 {
Ok(seq)
} else {
Err(de::Error::invalid_length(len, &"fewer elements in array"))
}
}
Value::Table(v) => {
let len = v.len();
let mut deserializer = MapDeserializer::new(v);
let map = visitor.visit_map(&mut deserializer)?;
let remaining = deserializer.iter.len();
if remaining == 0 {
Ok(map)
} else {
Err(de::Error::invalid_length(len, &"fewer elements in map"))
}
}
}
}
#[inline]
fn deserialize_enum<V>(
self,
_name: &str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, ::de::Error>
where
V: de::Visitor<'de>,
{
match self {
Value::String(variant) => visitor.visit_enum(variant.into_deserializer()),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"string only")),
}
}
// `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, ::de::Error>
where V: de::Visitor<'de>,
{
visitor.visit_some(self)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V
) -> Result<V::Value, ::de::Error>
where V: de::Visitor<'de>
{
visitor.visit_newtype_struct(self)
}
forward_to_deserialize_any! {
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
tuple ignored_any identifier
}
}
struct SeqDeserializer {
iter: vec::IntoIter<Value>,
}
impl SeqDeserializer {
fn new(vec: Vec<Value>) -> Self {
SeqDeserializer {
iter: vec.into_iter(),
}
}
}
impl<'de> de::SeqAccess<'de> for SeqDeserializer {
type Error = ::de::Error;
fn next_element_seed<T>(&mut self, seed: T)
-> Result<Option<T::Value>, ::de::Error>
where T: de::DeserializeSeed<'de>,
{
match self.iter.next() {
Some(value) => seed.deserialize(value).map(Some),
None => Ok(None),
}
}
fn size_hint(&self) -> Option<usize> {
match self.iter.size_hint() {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
}
struct MapDeserializer {
iter: <BTreeMap<String, Value> as IntoIterator>::IntoIter,
value: Option<(String, Value)>,
}
impl MapDeserializer {
fn new(map: BTreeMap<String, Value>) -> Self {
MapDeserializer {
iter: map.into_iter(),
value: None,
}
}
}
impl<'de> de::MapAccess<'de> for MapDeserializer {
type Error = ::de::Error;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, ::de::Error>
where T: de::DeserializeSeed<'de>,
{
match self.iter.next() {
Some((key, value)) => {
self.value = Some((key.clone(), value));
seed.deserialize(Value::String(key)).map(Some)
}
None => Ok(None),
}
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, ::de::Error>
where T: de::DeserializeSeed<'de>,
{
let (key, res) = match self.value.take() {
Some((key, value)) => (key, seed.deserialize(value)),
None => return Err(de::Error::custom("value is missing")),
};
res.map_err(|mut error| {
error.add_key_context(&key);
error
})
}
fn size_hint(&self) -> Option<usize> {
match self.iter.size_hint() {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
}
impl<'de> de::IntoDeserializer<'de, ::de::Error> for Value {
type Deserializer = Self;
fn into_deserializer(self) -> Self {
self
}
}
struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Value;
type Error = ::ser::Error;
type SerializeSeq = SerializeVec;
type SerializeTuple = ser::Impossible<Value, ::ser::Error>;
type SerializeTupleStruct = ser::Impossible<Value, ::ser::Error>;
type SerializeTupleVariant = ser::Impossible<Value, ::ser::Error>;
type SerializeMap = SerializeMap;
type SerializeStruct = SerializeMap;
type SerializeStructVariant = ser::Impossible<Value, ::ser::Error>;
fn serialize_bool(self, value: bool) -> Result<Value, ::ser::Error> {
Ok(Value::Boolean(value))
}
fn serialize_i8(self, value: i8) -> Result<Value, ::ser::Error> {
self.serialize_i64(value.into())
}
fn serialize_i16(self, value: i16) -> Result<Value, ::ser::Error> {
self.serialize_i64(value.into())
}
fn serialize_i32(self, value: i32) -> Result<Value, ::ser::Error> {
self.serialize_i64(value.into())
}
fn serialize_i64(self, value: i64) -> Result<Value, ::ser::Error> {
Ok(Value::Integer(value.into()))
}
fn serialize_u8(self, value: u8) -> Result<Value, ::ser::Error> {
self.serialize_i64(value.into())
}
fn serialize_u16(self, value: u16) -> Result<Value, ::ser::Error> {
self.serialize_i64(value.into())
}
fn serialize_u32(self, value: u32) -> Result<Value, ::ser::Error> {
self.serialize_i64(value.into())
}
fn serialize_u64(self, value: u64) -> Result<Value, ::ser::Error> {
if value <= i64::max_value() as u64 {
self.serialize_i64(value as i64)
} else {
Err(ser::Error::custom("u64 value was too large"))
}
}
fn serialize_f32(self, value: f32) -> Result<Value, ::ser::Error> {
self.serialize_f64(value.into())
}
fn serialize_f64(self, value: f64) -> Result<Value, ::ser::Error> {
Ok(Value::Float(value))
}
fn serialize_char(self, value: char) -> Result<Value, ::ser::Error> {
let mut s = String::new();
s.push(value);
self.serialize_str(&s)
}
fn serialize_str(self, value: &str) -> Result<Value, ::ser::Error> {
Ok(Value::String(value.to_owned()))
}
fn serialize_bytes(self, value: &[u8]) -> Result<Value, ::ser::Error> {
let vec = value.iter().map(|&b| Value::Integer(b.into())).collect();
Ok(Value::Array(vec))
}
fn serialize_unit(self) -> Result<Value, ::ser::Error> {
Err(::ser::Error::UnsupportedType)
}
fn serialize_unit_struct(self, _name: &'static str)
-> Result<Value, ::ser::Error> {
Err(::ser::Error::UnsupportedType)
}
fn serialize_unit_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str)
-> Result<Value, ::ser::Error> {
self.serialize_str(_variant)
}
fn serialize_newtype_struct<T: ?Sized>(self,
_name: &'static str,
value: &T)
-> Result<Value, ::ser::Error>
where T: ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T)
-> Result<Value, ::ser::Error>
where T: ser::Serialize,
{
Err(::ser::Error::UnsupportedType)
}
fn serialize_none(self) -> Result<Value, ::ser::Error> {
Err(::ser::Error::UnsupportedNone)
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, ::ser::Error>
where T: ser::Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>)
-> Result<Self::SerializeSeq, ::ser::Error>
{
Ok(SerializeVec {
vec: Vec::with_capacity(len.unwrap_or(0))
})
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, ::ser::Error> {
Err(::ser::Error::UnsupportedType)
}
fn serialize_tuple_struct(self, _name: &'static str, _len: usize)
-> Result<Self::SerializeTupleStruct, ::ser::Error> {
Err(::ser::Error::UnsupportedType)
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize)
-> Result<Self::SerializeTupleVariant, ::ser::Error>
{
Err(::ser::Error::UnsupportedType)
}
fn serialize_map(self, _len: Option<usize>)
-> Result<Self::SerializeMap, ::ser::Error>
{
Ok(SerializeMap {
map: BTreeMap::new(),
next_key: None,
})
}
fn serialize_struct(self, _name: &'static str, len: usize)
-> Result<Self::SerializeStruct, ::ser::Error> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize)
-> Result<Self::SerializeStructVariant, ::ser::Error>
{
Err(::ser::Error::UnsupportedType)
}
}
struct SerializeVec {
vec: Vec<Value>,
}
struct SerializeMap {
map: BTreeMap<String, Value>,
next_key: Option<String>,
}
impl ser::SerializeSeq for SerializeVec {
type Ok = Value;
type Error = ::ser::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error>
where T: ser::Serialize
{
self.vec.push(Value::try_from(value)?);
Ok(())
}
fn end(self) -> Result<Value, ::ser::Error> {
Ok(Value::Array(self.vec))
}
}
impl ser::SerializeMap for SerializeMap {
type Ok = Value;
type Error = ::ser::Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), ::ser::Error>
where T: ser::Serialize
{
match Value::try_from(key)? {
Value::String(s) => self.next_key = Some(s),
_ => return Err(::ser::Error::KeyNotString),
};
Ok(())
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error>
where T: ser::Serialize
{
let key = self.next_key.take();
let key = key.expect("serialize_value called before serialize_key");
match Value::try_from(value) {
Ok(value) => { self.map.insert(key, value); }
Err(::ser::Error::UnsupportedNone) => {}
Err(e) => return Err(e),
}
Ok(())
}
fn end(self) -> Result<Value, ::ser::Error> {
Ok(Value::Table(self.map))
}
}
impl ser::SerializeStruct for SerializeMap {
type Ok = Value;
type Error = ::ser::Error;
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), ::ser::Error>
where T: ser::Serialize
{
try!(ser::SerializeMap::serialize_key(self, key));
ser::SerializeMap::serialize_value(self, value)
}
fn end(self) -> Result<Value, ::ser::Error> {
ser::SerializeMap::end(self)
}
}
struct DatetimeOrTable<'a> {
key: &'a mut String,
}
impl<'a, 'de> de::DeserializeSeed<'de> for DatetimeOrTable<'a> {
type Value = bool;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where D: de::Deserializer<'de>
{
deserializer.deserialize_any(self)
}
}
impl<'a, 'de> de::Visitor<'de> for DatetimeOrTable<'a> {
type Value = bool;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string key")
}
fn visit_str<E>(self, s: &str) -> Result<bool, E>
where E: de::Error,
{
if s == SERDE_STRUCT_FIELD_NAME {
Ok(true)
} else {
self.key.push_str(s);
Ok(false)
}
}
fn visit_string<E>(self, s: String) -> Result<bool, E>
where E: de::Error,
{
if s == SERDE_STRUCT_FIELD_NAME {
Ok(true)
} else {
*self.key = s;
Ok(false)
}
}
}

19
third_party/rust/toml/tests/backcompat.rs поставляемый
Просмотреть файл

@ -1,19 +0,0 @@
extern crate toml;
extern crate serde;
use serde::de::Deserialize;
#[test]
fn main() {
let s = "
[a] foo = 1
[[b]] foo = 1
";
assert!(s.parse::<toml::Value>().is_err());
let mut d = toml::de::Deserializer::new(s);
d.set_require_newline_after_table(false);
let value = toml::Value::deserialize(&mut d).unwrap();
assert_eq!(value["a"]["foo"].as_integer(), Some(1));
assert_eq!(value["b"][0]["foo"].as_integer(), Some(1));
}

58
third_party/rust/toml/tests/datetime.rs поставляемый
Просмотреть файл

@ -1,58 +0,0 @@
extern crate toml;
use std::str::FromStr;
use toml::Value;
#[test]
fn times() {
fn good(s: &str) {
let to_parse = format!("foo = {}", s);
let value = Value::from_str(&to_parse).unwrap();
assert_eq!(value["foo"].as_datetime().unwrap().to_string(), s);
}
good("1997-09-09T09:09:09Z");
good("1997-09-09T09:09:09+09:09");
good("1997-09-09T09:09:09-09:09");
good("1997-09-09T09:09:09");
good("1997-09-09");
good("09:09:09");
good("1997-09-09T09:09:09.09Z");
good("1997-09-09T09:09:09.09+09:09");
good("1997-09-09T09:09:09.09-09:09");
good("1997-09-09T09:09:09.09");
good("09:09:09.09");
}
#[test]
fn bad_times() {
fn bad(s: &str) {
let to_parse = format!("foo = {}", s);
assert!(Value::from_str(&to_parse).is_err());
}
bad("199-09-09");
bad("199709-09");
bad("1997-9-09");
bad("1997-09-9");
bad("1997-09-0909:09:09");
bad("1997-09-09T09:09:09.");
bad("T");
bad("T.");
bad("TZ");
bad("1997-09-09T09:09:09.09+");
bad("1997-09-09T09:09:09.09+09");
bad("1997-09-09T09:09:09.09+09:9");
bad("1997-09-09T09:09:09.09+0909");
bad("1997-09-09T09:09:09.09-");
bad("1997-09-09T09:09:09.09-09");
bad("1997-09-09T09:09:09.09-09:9");
bad("1997-09-09T09:09:09.09-0909");
bad("1997-00-09T09:09:09.09Z");
bad("1997-09-00T09:09:09.09Z");
bad("1997-09-09T30:09:09.09Z");
bad("1997-09-09T12:69:09.09Z");
bad("1997-09-09T12:09:69.09Z");
}

49
third_party/rust/toml/tests/display-tricky.rs поставляемый
Просмотреть файл

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

103
third_party/rust/toml/tests/display.rs поставляемый
Просмотреть файл

@ -1,103 +0,0 @@
extern crate toml;
use std::collections::BTreeMap;
use toml::Value::{String, Integer, Float, Boolean, Array, Table};
macro_rules! map( ($($k:expr => $v:expr),*) => ({
let mut _m = BTreeMap::new();
$(_m.insert($k.to_string(), $v);)*
_m
}) );
#[test]
fn simple_show() {
assert_eq!(String("foo".to_string()).to_string(),
"\"foo\"");
assert_eq!(Integer(10).to_string(),
"10");
assert_eq!(Float(10.0).to_string(),
"10.0");
assert_eq!(Float(2.4).to_string(),
"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]
fn table() {
assert_eq!(Table(map! { }).to_string(),
"");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Integer(3) }).to_string(),
"test = 2\ntest2 = 3\n");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Table(map! {
"test" => String("wut".to_string())
})
}).to_string(),
"test = 2\n\
\n\
[test2]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Table(map! {
"test" => String("wut".to_string())
})
}).to_string(),
"test = 2\n\
\n\
[test2]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"test" => Integer(2),
"test2" => Array(vec![Table(map! {
"test" => String("wut".to_string())
})])
}).to_string(),
"test = 2\n\
\n\
[[test2]]\n\
test = \"wut\"\n");
assert_eq!(Table(map! {
"foo.bar" => Integer(2),
"foo\"bar" => Integer(2)
}).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! {
"test" => Integer(2),
"test2" => Array(vec![Table(map! {
"test" => Array(vec![Array(vec![Integer(2), Integer(3)]),
Array(vec![String("foo".to_string()), String("bar".to_string())])])
})])
});
assert_eq!(table.to_string(),
"test = 2\n\
\n\
[[test2]]\n\
test = [[2, 3], [\"foo\", \"bar\"]]\n");
assert_eq!(Table(map! {
"test" => Array(vec![Integer(2)]),
"test2" => Integer(2)
}).to_string(),
"test = [2]\n\
test2 = 2\n");
}

21
third_party/rust/toml/tests/formatting.rs поставляемый
Просмотреть файл

@ -1,22 +1,19 @@
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate rustc_serialize;
extern crate toml;
use toml::encode_str;
use toml::to_string;
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
struct User {
pub name: String,
pub surname: String,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
struct Users {
pub user: Vec<User>,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
struct TwoUsers {
pub user0: User,
pub user1: User,
@ -24,7 +21,7 @@ struct TwoUsers {
#[test]
fn no_unnecessary_newlines_array() {
assert!(!to_string(&Users {
assert!(!encode_str(&Users {
user: vec![
User {
name: "John".to_string(),
@ -35,13 +32,13 @@ fn no_unnecessary_newlines_array() {
surname: "Dough".to_string(),
},
],
}).unwrap()
})
.starts_with("\n"));
}
#[test]
fn no_unnecessary_newlines_table() {
assert!(!to_string(&TwoUsers {
assert!(!encode_str(&TwoUsers {
user0: User {
name: "John".to_string(),
surname: "Doe".to_string(),
@ -50,6 +47,6 @@ fn no_unnecessary_newlines_table() {
name: "Jane".to_string(),
surname: "Dough".to_string(),
},
}).unwrap()
})
.starts_with("\n"));
}

Просмотреть файл

@ -1,14 +0,0 @@
extern crate toml;
use std::f64;
#[test]
fn test_invalid_float_encode() {
fn bad(value: toml::Value) {
assert!(toml::to_string(&value).is_err());
}
bad(toml::Value::Float(f64::INFINITY));
bad(toml::Value::Float(f64::NEG_INFINITY));
bad(toml::Value::Float(f64::NAN));
}

17
third_party/rust/toml/tests/invalid-misc.rs поставляемый
Просмотреть файл

@ -1,17 +0,0 @@
extern crate toml;
#[test]
fn bad() {
fn bad(s: &str) {
assert!(s.parse::<toml::Value>().is_err());
}
bad("a = 01");
bad("a = 1__1");
bad("a = 1_");
bad("''");
bad("a = nan");
bad("a = -inf");
bad("a = inf");
bad("a = 9e99999");
}

16
third_party/rust/toml/tests/invalid.rs поставляемый
Просмотреть файл

@ -1,9 +1,17 @@
extern crate toml;
use toml::{Parser};
fn run(toml: &str) {
println!("test if invalid:\n{}", toml);
if let Ok(e) = toml.parse::<toml::Value>() {
panic!("parsed to: {:#?}", e);
let mut p = Parser::new(toml);
let table = p.parse();
assert!(table.is_none());
assert!(p.errors.len() > 0);
// test Parser::to_linecol with the generated error offsets
for error in &p.errors {
p.to_linecol(error.lo);
p.to_linecol(error.hi);
}
}
@ -24,6 +32,8 @@ test!(datetime_malformed_no_secs,
include_str!("invalid/datetime-malformed-no-secs.toml"));
test!(datetime_malformed_no_t,
include_str!("invalid/datetime-malformed-no-t.toml"));
test!(datetime_malformed_no_z,
include_str!("invalid/datetime-malformed-no-z.toml"));
test!(datetime_malformed_with_milli,
include_str!("invalid/datetime-malformed-with-milli.toml"));
test!(duplicate_keys,

Просмотреть файл

@ -0,0 +1 @@
no-z = 1987-07-05T17:45:00

495
third_party/rust/toml/tests/parser.rs поставляемый
Просмотреть файл

@ -1,495 +0,0 @@
extern crate toml;
use toml::Value;
macro_rules! bad {
($s:expr, $msg:expr) => ({
match $s.parse::<Value>() {
Ok(s) => panic!("successfully parsed as {}", s),
Err(e) => {
let e = e.to_string();
assert!(e.contains($msg), "error: {}", e);
}
}
})
}
#[test]
fn crlf() {
"\
[project]\r\n\
\r\n\
name = \"splay\"\r\n\
version = \"0.1.0\"\r\n\
authors = [\"alex@crichton.co\"]\r\n\
\r\n\
[[lib]]\r\n\
\r\n\
path = \"lib.rs\"\r\n\
name = \"splay\"\r\n\
description = \"\"\"\
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\
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\
\"\"\"\
".parse::<Value>().unwrap();
}
#[test]
fn fun_with_strings() {
let table = r#"
bar = "\U00000000"
key1 = "One\nTwo"
key2 = """One\nTwo"""
key3 = """
One
Two"""
key4 = "The quick brown fox jumps over the lazy dog."
key5 = """
The quick brown \
fox jumps over \
the lazy dog."""
key6 = """\
The quick brown \
fox jumps over \
the lazy dog.\
"""
# What you see is what you get.
winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted = 'Tom "Dubs" Preston-Werner'
regex = '<\i\c*\s*>'
regex2 = '''I [dw]on't need \d{2} apples'''
lines = '''
The first newline is
trimmed in raw strings.
All other whitespace
is preserved.
'''
"#.parse::<Value>().unwrap();
assert_eq!(table["bar"].as_str(), Some("\0"));
assert_eq!(table["key1"].as_str(), Some("One\nTwo"));
assert_eq!(table["key2"].as_str(), Some("One\nTwo"));
assert_eq!(table["key3"].as_str(), Some("One\nTwo"));
let msg = "The quick brown fox jumps over the lazy dog.";
assert_eq!(table["key4"].as_str(), Some(msg));
assert_eq!(table["key5"].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!(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["regex2"].as_str(), Some(r"I [dw]on't need \d{2} apples"));
assert_eq!(table["lines"].as_str(),
Some("The first newline is\n\
trimmed in raw strings.\n\
All other whitespace\n\
is preserved.\n"));
}
#[test]
fn tables_in_arrays() {
let table = r#"
[[foo]]
#
[foo.bar]
#
[[foo]] # ...
#
[foo.bar]
#...
"#.parse::<Value>().unwrap();
table["foo"][0]["bar"].as_table().unwrap();
table["foo"][1]["bar"].as_table().unwrap();
}
#[test]
fn empty_table() {
let table = r#"
[foo]"#.parse::<Value>().unwrap();
table["foo"].as_table().unwrap();
}
#[test]
fn fruit() {
let table = r#"
[[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"
"#.parse::<Value>().unwrap();
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"]["shape"].as_str(), 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]["variety"][0]["name"].as_str(), Some("plantain"));
}
#[test]
fn stray_cr() {
"\r".parse::<Value>().unwrap_err();
"a = [ \r ]".parse::<Value>().unwrap_err();
"a = \"\"\"\r\"\"\"".parse::<Value>().unwrap_err();
"a = \"\"\"\\ \r \"\"\"".parse::<Value>().unwrap_err();
"a = '''\r'''".parse::<Value>().unwrap_err();
"a = '\r'".parse::<Value>().unwrap_err();
"a = \"\r\"".parse::<Value>().unwrap_err();
}
#[test]
fn blank_literal_string() {
let table = "foo = ''".parse::<Value>().unwrap();
assert_eq!(table["foo"].as_str(), Some(""));
}
#[test]
fn many_blank() {
let table = "foo = \"\"\"\n\n\n\"\"\"".parse::<Value>().unwrap();
assert_eq!(table["foo"].as_str(), Some("\n\n"));
}
#[test]
fn literal_eats_crlf() {
let table = "
foo = \"\"\"\\\r\n\"\"\"
bar = \"\"\"\\\r\n \r\n \r\n a\"\"\"
".parse::<Value>().unwrap();
assert_eq!(table["foo"].as_str(), Some(""));
assert_eq!(table["bar"].as_str(), Some("a"));
}
#[test]
fn string_no_newline() {
"a = \"\n\"".parse::<Value>().unwrap_err();
"a = '\n'".parse::<Value>().unwrap_err();
}
#[test]
fn bad_leading_zeros() {
"a = 00".parse::<Value>().unwrap_err();
"a = -00".parse::<Value>().unwrap_err();
"a = +00".parse::<Value>().unwrap_err();
"a = 00.0".parse::<Value>().unwrap_err();
"a = -00.0".parse::<Value>().unwrap_err();
"a = +00.0".parse::<Value>().unwrap_err();
"a = 9223372036854775808".parse::<Value>().unwrap_err();
"a = -9223372036854775809".parse::<Value>().unwrap_err();
}
#[test]
fn bad_floats() {
"a = 0.".parse::<Value>().unwrap_err();
"a = 0.e".parse::<Value>().unwrap_err();
"a = 0.E".parse::<Value>().unwrap_err();
"a = 0.0E".parse::<Value>().unwrap_err();
"a = 0.0e".parse::<Value>().unwrap_err();
"a = 0.0e-".parse::<Value>().unwrap_err();
"a = 0.0e+".parse::<Value>().unwrap_err();
"a = 0.0e+00".parse::<Value>().unwrap_err();
}
#[test]
fn floats() {
macro_rules! t {
($actual:expr, $expected:expr) => ({
let f = format!("foo = {}", $actual);
println!("{}", f);
let a = f.parse::<Value>().unwrap();
assert_eq!(a["foo"].as_float().unwrap(), $expected);
})
}
t!("1.0", 1.0);
t!("1.0e0", 1.0);
t!("1.0e+0", 1.0);
t!("1.0e-0", 1.0);
t!("1.001e-0", 1.001);
t!("2e10", 2e10);
t!("2e+10", 2e10);
t!("2e-10", 2e-10);
t!("2_0.0", 20.0);
t!("2_0.0_0e1_0", 20.0e10);
t!("2_0.1_0e1_0", 20.1e10);
}
#[test]
fn bare_key_names() {
let a = "
foo = 3
foo_3 = 3
foo_-2--3--r23f--4-f2-4 = 3
_ = 3
- = 3
8 = 8
\"a\" = 3
\"!\" = 3
\"a^b\" = 3
\"\\\"\" = 3
\"character encoding\" = \"value\"
'ʎǝʞ' = \"value\"
".parse::<Value>().unwrap();
&a["foo"];
&a["-"];
&a["_"];
&a["8"];
&a["foo_3"];
&a["foo_-2--3--r23f--4-f2-4"];
&a["a"];
&a["!"];
&a["\""];
&a["character encoding"];
&a["ʎǝʞ"];
}
#[test]
fn bad_keys() {
"key\n=3".parse::<Value>().unwrap_err();
"key=\n3".parse::<Value>().unwrap_err();
"key|=3".parse::<Value>().unwrap_err();
"\"\"=3".parse::<Value>().unwrap_err();
"=3".parse::<Value>().unwrap_err();
"\"\"|=3".parse::<Value>().unwrap_err();
"\"\n\"|=3".parse::<Value>().unwrap_err();
"\"\r\"|=3".parse::<Value>().unwrap_err();
}
#[test]
fn bad_table_names() {
"[]".parse::<Value>().unwrap_err();
"[.]".parse::<Value>().unwrap_err();
"[\"\".\"\"]".parse::<Value>().unwrap_err();
"[a.]".parse::<Value>().unwrap_err();
"[\"\"]".parse::<Value>().unwrap_err();
"[!]".parse::<Value>().unwrap_err();
"[\"\n\"]".parse::<Value>().unwrap_err();
"[a.b]\n[a.\"b\"]".parse::<Value>().unwrap_err();
"[']".parse::<Value>().unwrap_err();
"[''']".parse::<Value>().unwrap_err();
"['''''']".parse::<Value>().unwrap_err();
"['\n']".parse::<Value>().unwrap_err();
"['\r\n']".parse::<Value>().unwrap_err();
}
#[test]
fn table_names() {
let a = "
[a.\"b\"]
[\"f f\"]
[\"f.f\"]
[\"\\\"\"]
['a.a']
['\"\"']
".parse::<Value>().unwrap();
println!("{:?}", a);
&a["a"]["b"];
&a["f f"];
&a["f.f"];
&a["\""];
&a["\"\""];
}
#[test]
fn invalid_bare_numeral() {
"4".parse::<Value>().unwrap_err();
}
#[test]
fn inline_tables() {
"a = {}".parse::<Value>().unwrap();
"a = {b=1}".parse::<Value>().unwrap();
"a = { b = 1 }".parse::<Value>().unwrap();
"a = {a=1,b=2}".parse::<Value>().unwrap();
"a = {a=1,b=2,c={}}".parse::<Value>().unwrap();
"a = {a=1,}".parse::<Value>().unwrap_err();
"a = {,}".parse::<Value>().unwrap_err();
"a = {a=1,a=1}".parse::<Value>().unwrap_err();
"a = {\n}".parse::<Value>().unwrap_err();
"a = {".parse::<Value>().unwrap_err();
"a = {a=[\n]}".parse::<Value>().unwrap();
"a = {\"a\"=[\n]}".parse::<Value>().unwrap();
"a = [\n{},\n{},\n]".parse::<Value>().unwrap();
}
#[test]
fn number_underscores() {
macro_rules! t {
($actual:expr, $expected:expr) => ({
let f = format!("foo = {}", $actual);
let table = f.parse::<Value>().unwrap();
assert_eq!(table["foo"].as_integer().unwrap(), $expected);
})
}
t!("1_0", 10);
t!("1_0_0", 100);
t!("1_000", 1000);
t!("+1_000", 1000);
t!("-1_000", -1000);
}
#[test]
fn bad_underscores() {
bad!("foo = 0_", "invalid number");
bad!("foo = 0__0", "invalid number");
bad!("foo = __0", "invalid number");
bad!("foo = 1_0_", "invalid number");
}
#[test]
fn bad_unicode_codepoint() {
bad!("foo = \"\\uD800\"", "invalid escape value");
}
#[test]
fn bad_strings() {
bad!("foo = \"\\uxx\"", "invalid hex escape");
bad!("foo = \"\\u\"", "invalid hex escape");
bad!("foo = \"\\", "unterminated");
bad!("foo = '", "unterminated");
}
#[test]
fn empty_string() {
assert_eq!("foo = \"\"".parse::<Value>()
.unwrap()["foo"]
.as_str()
.unwrap(),
"");
}
#[test]
fn booleans() {
let table = "foo = true".parse::<Value>().unwrap();
assert_eq!(table["foo"].as_bool(), Some(true));
let table = "foo = false".parse::<Value>().unwrap();
assert_eq!(table["foo"].as_bool(), Some(false));
assert!("foo = true2".parse::<Value>().is_err());
assert!("foo = false2".parse::<Value>().is_err());
assert!("foo = t1".parse::<Value>().is_err());
assert!("foo = f2".parse::<Value>().is_err());
}
#[test]
fn bad_nesting() {
bad!("
a = [2]
[[a]]
b = 5
", "duplicate key: `a`");
bad!("
a = 1
[a.b]
", "duplicate key: `a`");
bad!("
a = []
[a.b]
", "duplicate key: `a`");
bad!("
a = []
[[a.b]]
", "duplicate key: `a`");
bad!("
[a]
b = { c = 2, d = {} }
[a.b]
c = 2
", "duplicate key: `b`");
}
#[test]
fn bad_table_redefine() {
bad!("
[a]
foo=\"bar\"
[a.b]
foo=\"bar\"
[a]
", "redefinition of table `a`");
bad!("
[a]
foo=\"bar\"
b = { foo = \"bar\" }
[a]
", "redefinition of table `a`");
bad!("
[a]
b = {}
[a.b]
", "duplicate key: `b`");
bad!("
[a]
b = {}
[a]
", "redefinition of table `a`");
}
#[test]
fn datetimes() {
macro_rules! t {
($actual:expr) => ({
let f = format!("foo = {}", $actual);
let toml = f.parse::<Value>().expect(&format!("failed: {}", f));
assert_eq!(toml["foo"].as_datetime().unwrap().to_string(), $actual);
})
}
t!("2016-09-09T09:09:09Z");
t!("2016-09-09T09:09:09.1Z");
t!("2016-09-09T09:09:09.2+10:00");
t!("2016-09-09T09:09:09.123456789-02:00");
bad!("foo = 2016-09-09T09:09:09.Z", "failed to parse date");
bad!("foo = 2016-9-09T09:09:09Z", "failed to parse date");
bad!("foo = 2016-09-09T09:09:09+2:00", "failed to parse date");
bad!("foo = 2016-09-09T09:09:09-2:00", "failed to parse date");
bad!("foo = 2016-09-09T09:09:09Z-2:00", "failed to parse date");
}
#[test]
fn require_newline_after_value() {
bad!("0=0r=false", "invalid number at line 1");
bad!(r#"
0=""o=""m=""r=""00="0"q="""0"""e="""0"""
"#, "expected newline");
bad!(r#"
[[0000l0]]
0="0"[[0000l0]]
0="0"[[0000l0]]
0="0"l="0"
"#, "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]
"#, "expected newline");
bad!(r#"
0=0r0=0r=false
"#, "invalid number at line 2");
bad!(r#"
0=0r0=0r=falsefal=false
"#, "invalid number at line 2");
}

308
third_party/rust/toml/tests/pretty.rs поставляемый
Просмотреть файл

@ -1,308 +0,0 @@
extern crate toml;
extern crate serde;
use serde::ser::Serialize;
const NO_PRETTY: &'static str = "\
[example]
array = [\"item 1\", \"item 2\"]
empty = []
oneline = \"this has no newlines.\"
text = \"\\nthis is the first line\\nthis is the second line\\n\"
";
#[test]
fn no_pretty() {
let toml = NO_PRETTY;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::new(&mut result)).unwrap();
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
#[test]
fn disable_pretty() {
let toml = NO_PRETTY;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_string(false);
serializer.pretty_array(false);
value.serialize(&mut serializer).unwrap();
}
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
const PRETTY_STD: &'static str = "\
[example]
array = [
'item 1',
'item 2',
]
empty = []
one = ['one']
oneline = 'this has no newlines.'
text = '''
this is the first line
this is the second line
'''
";
#[test]
fn pretty_std() {
let toml = PRETTY_STD;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap();
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
const PRETTY_INDENT_2: &'static str = "\
[example]
array = [
'item 1',
'item 2',
]
empty = []
one = ['one']
oneline = 'this has no newlines.'
text = '''
this is the first line
this is the second line
'''
three = [
'one',
'two',
'three',
]
";
#[test]
fn pretty_indent_2() {
let toml = PRETTY_INDENT_2;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_array_indent(2);
value.serialize(&mut serializer).unwrap();
}
println!(">> Result:\n{}", result);
assert_eq!(toml, &result);
}
const PRETTY_INDENT_2_OTHER: &'static str = "\
[example]
array = [
\"item 1\",
\"item 2\",
]
empty = []
oneline = \"this has no newlines.\"
text = \"\\nthis is the first line\\nthis is the second line\\n\"
";
#[test]
/// Test pretty indent when gotten the other way
fn pretty_indent_2_other() {
let toml = PRETTY_INDENT_2_OTHER;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::new(&mut result);
serializer.pretty_array_indent(2);
value.serialize(&mut serializer).unwrap();
}
assert_eq!(toml, &result);
}
const PRETTY_ARRAY_NO_COMMA: &'static str = "\
[example]
array = [
\"item 1\",
\"item 2\"
]
empty = []
oneline = \"this has no newlines.\"
text = \"\\nthis is the first line\\nthis is the second line\\n\"
";
#[test]
/// Test pretty indent when gotten the other way
fn pretty_indent_array_no_comma() {
let toml = PRETTY_ARRAY_NO_COMMA;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::new(&mut result);
serializer.pretty_array_trailing_comma(false);
value.serialize(&mut serializer).unwrap();
}
assert_eq!(toml, &result);
}
const PRETTY_NO_STRING: &'static str = "\
[example]
array = [
\"item 1\",
\"item 2\",
]
empty = []
oneline = \"this has no newlines.\"
text = \"\\nthis is the first line\\nthis is the second line\\n\"
";
#[test]
/// Test pretty indent when gotten the other way
fn pretty_no_string() {
let toml = PRETTY_NO_STRING;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_string(false);
value.serialize(&mut serializer).unwrap();
}
assert_eq!(toml, &result);
}
const PRETTY_TRICKY: &'static str = r##"[example]
f = "\f"
glass = '''
Nothing too unusual, except that I can eat glass in:
- Greek: Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.
- Polish: Mogę jeść szkło, i mi nie szkodzi.
- Hindi: , .
- Japanese:
'''
r = "\r"
r_newline = """
\r
"""
single = '''this is a single line but has '' cuz it's tricky'''
single_tricky = "single line with ''' in it"
tabs = '''
this is pretty standard
except for some tabs right here
'''
text = """
this is the first line.
This has a ''' in it and \"\"\" cuz it's tricky yo
Also ' and \" because why not
this is the fourth line
"""
"##;
#[test]
fn pretty_tricky() {
let toml = PRETTY_TRICKY;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap();
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
const PRETTY_TABLE_ARRAY: &'static str = r##"[[array]]
key = 'foo'
[[array]]
key = 'bar'
[abc]
doc = 'this is a table'
[example]
single = 'this is a single line string'
"##;
#[test]
fn pretty_table_array() {
let toml = PRETTY_TABLE_ARRAY;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::pretty(&mut result)).unwrap();
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
const TABLE_ARRAY: &'static str = r##"[[array]]
key = "foo"
[[array]]
key = "bar"
[abc]
doc = "this is a table"
[example]
single = "this is a single line string"
"##;
#[test]
fn table_array() {
let toml = TABLE_ARRAY;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
value.serialize(&mut toml::Serializer::new(&mut result)).unwrap();
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}
const PRETTY_TRICKY_NON_LITERAL: &'static str = r##"[example]
f = "\f"
glass = """
Nothing too unusual, except that I can eat glass in:
- Greek: Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.
- Polish: Mogę jeść szkło, i mi nie szkodzi.
- Hindi: , .
- Japanese:
"""
plain = """
This has a couple of lines
Because it likes to.
"""
r = "\r"
r_newline = """
\r
"""
single = "this is a single line but has '' cuz it's tricky"
single_tricky = "single line with ''' in it"
tabs = """
this is pretty standard
\texcept for some \ttabs right here
"""
text = """
this is the first line.
This has a ''' in it and \"\"\" cuz it's tricky yo
Also ' and \" because why not
this is the fourth line
"""
"##;
#[test]
fn pretty_tricky_non_literal() {
let toml = PRETTY_TRICKY_NON_LITERAL;
let value: toml::Value = toml::from_str(toml).unwrap();
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_string_literal(false);
value.serialize(&mut serializer).unwrap();
}
println!("EXPECTED:\n{}", toml);
println!("\nRESULT:\n{}", result);
assert_eq!(toml, &result);
}

578
third_party/rust/toml/tests/serde.rs поставляемый
Просмотреть файл

@ -1,578 +0,0 @@
extern crate serde;
extern crate toml;
#[macro_use]
extern crate serde_derive;
use std::collections::{BTreeMap, HashSet};
use serde::{Deserialize, Deserializer};
use toml::Value;
use toml::Value::{Table, Integer, Array, Float};
macro_rules! t {
($e:expr) => (match $e {
Ok(t) => t,
Err(e) => panic!("{} failed with {}", stringify!($e), e),
})
}
macro_rules! equivalent {
($literal:expr, $toml:expr,) => ({
let toml = $toml;
let literal = $literal;
// In/out of Value is equivalent
println!("try_from");
assert_eq!(t!(Value::try_from(literal.clone())), toml);
println!("try_into");
assert_eq!(literal, t!(toml.clone().try_into()));
// Through a string equivalent
println!("to_string(literal)");
assert_eq!(t!(toml::to_string(&literal)), toml.to_string());
println!("to_string(toml)");
assert_eq!(t!(toml::to_string(&toml)), toml.to_string());
println!("literal, from_str(toml)");
assert_eq!(literal, t!(toml::from_str(&toml.to_string())));
println!("toml, from_str(toml)");
assert_eq!(toml, t!(toml::from_str(&toml.to_string())));
})
}
macro_rules! error {
($ty:ty, $toml:expr, $error:expr) => ({
println!("attempting parsing");
match toml::from_str::<$ty>(&$toml.to_string()) {
Ok(_) => panic!("successful"),
Err(e) => {
assert!(e.to_string().contains($error),
"bad error: {}", e);
}
}
println!("attempting toml decoding");
match $toml.try_into::<$ty>() {
Ok(_) => panic!("successful"),
Err(e) => {
assert!(e.to_string().contains($error),
"bad error: {}", e);
}
}
})
}
macro_rules! map( ($($k:ident: $v:expr),*) => ({
let mut _m = BTreeMap::new();
$(_m.insert(stringify!($k).to_string(), $v);)*
_m
}) );
#[test]
fn smoke() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: isize }
equivalent!(
Foo { a: 2 },
Table(map! { a: Integer(2) }),
);
}
#[test]
fn smoke_hyphen() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo {
a_b: isize,
}
equivalent! {
Foo { a_b: 2 },
Table(map! { a_b: Integer(2) }),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo2 {
#[serde(rename = "a-b")]
a_b: isize,
}
let mut m = BTreeMap::new();
m.insert("a-b".to_string(), Integer(2));
equivalent! {
Foo2 { a_b: 2 },
Table(m),
}
}
#[test]
fn nested() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: isize, b: Bar }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar { a: String }
equivalent! {
Foo { a: 2, b: Bar { a: "test".to_string() } },
Table(map! {
a: Integer(2),
b: Table(map! {
a: Value::String("test".to_string())
})
}),
}
}
#[test]
fn application_decode_error() {
#[derive(PartialEq, Debug)]
struct Range10(usize);
impl<'de> Deserialize<'de> for Range10 {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Range10, D::Error> {
let x: usize = try!(Deserialize::deserialize(d));
if x > 10 {
Err(serde::de::Error::custom("more than 10"))
} else {
Ok(Range10(x))
}
}
}
let d_good = Integer(5);
let d_bad1 = Value::String("not an isize".to_string());
let d_bad2 = Integer(11);
assert_eq!(Range10(5), d_good.try_into().unwrap());
let err1: Result<Range10, _> = d_bad1.try_into();
assert!(err1.is_err());
let err2: Result<Range10, _> = d_bad2.try_into();
assert!(err2.is_err());
}
#[test]
fn array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<isize> }
equivalent! {
Foo { a: vec![1, 2, 3, 4] },
Table(map! {
a: Array(vec![
Integer(1),
Integer(2),
Integer(3),
Integer(4)
])
}),
};
}
#[test]
fn inner_structs_with_options() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo {
a: Option<Box<Foo>>,
b: Bar,
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar {
a: String,
b: f64,
}
equivalent! {
Foo {
a: Some(Box::new(Foo {
a: None,
b: Bar { a: "foo".to_string(), b: 4.5 },
})),
b: Bar { a: "bar".to_string(), b: 1.0 },
},
Table(map! {
a: Table(map! {
b: Table(map! {
a: Value::String("foo".to_string()),
b: Float(4.5)
})
}),
b: Table(map! {
a: Value::String("bar".to_string()),
b: Float(1.0)
})
}),
}
}
#[test]
fn hashmap() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo {
set: HashSet<char>,
map: BTreeMap<String, isize>,
}
equivalent! {
Foo {
map: {
let mut m = BTreeMap::new();
m.insert("foo".to_string(), 10);
m.insert("bar".to_string(), 4);
m
},
set: {
let mut s = HashSet::new();
s.insert('a');
s
},
},
Table(map! {
map: Table(map! {
foo: Integer(10),
bar: Integer(4)
}),
set: Array(vec![Value::String("a".to_string())])
}),
}
}
#[test]
fn table_array() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<Bar>, }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar { a: isize }
equivalent! {
Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] },
Table(map! {
a: Array(vec![
Table(map!{ a: Integer(1) }),
Table(map!{ a: Integer(2) }),
])
}),
}
}
#[test]
fn type_errors() {
#[derive(Deserialize)]
#[allow(dead_code)]
struct Foo { bar: isize }
error! {
Foo,
Table(map! {
bar: Value::String("a".to_string())
}),
"invalid type: string \"a\", expected isize for key `bar`"
}
#[derive(Deserialize)]
#[allow(dead_code)]
struct Bar { foo: Foo }
error! {
Bar,
Table(map! {
foo: Table(map! {
bar: Value::String("a".to_string())
})
}),
"invalid type: string \"a\", expected isize for key `foo.bar`"
}
}
#[test]
fn missing_errors() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Foo { bar: isize }
error! {
Foo,
Table(map! { }),
"missing field `bar`"
}
}
#[test]
fn parse_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: E }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(untagged)]
enum E {
Bar(isize),
Baz(String),
Last(Foo2),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo2 {
test: String,
}
equivalent! {
Foo { a: E::Bar(10) },
Table(map! { a: Integer(10) }),
}
equivalent! {
Foo { a: E::Baz("foo".to_string()) },
Table(map! { a: Value::String("foo".to_string()) }),
}
equivalent! {
Foo { a: E::Last(Foo2 { test: "test".to_string() }) },
Table(map! { a: Table(map! { test: Value::String("test".to_string()) }) }),
}
}
#[test]
fn parse_enum_string() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Sort }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(rename_all = "lowercase")]
enum Sort {
Asc,
Desc,
}
equivalent! {
Foo { a: Sort::Desc },
Table(map! { a: Value::String("desc".to_string()) }),
}
}
// #[test]
// fn unused_fields() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: isize }
//
// let v = Foo { a: 2 };
// let mut d = Decoder::new(Table(map! {
// a, Integer(2),
// b, Integer(5)
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, Some(Table(map! {
// b, Integer(5)
// })));
// }
//
// #[test]
// fn unused_fields2() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: Bar }
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Bar { a: isize }
//
// let v = Foo { a: Bar { a: 2 } };
// let mut d = Decoder::new(Table(map! {
// a, Table(map! {
// a, Integer(2),
// b, Integer(5)
// })
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, Some(Table(map! {
// a, Table(map! {
// b, Integer(5)
// })
// })));
// }
//
// #[test]
// fn unused_fields3() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: Bar }
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Bar { a: isize }
//
// let v = Foo { a: Bar { a: 2 } };
// let mut d = Decoder::new(Table(map! {
// a, Table(map! {
// a, Integer(2)
// })
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, None);
// }
//
// #[test]
// fn unused_fields4() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: BTreeMap<String, String> }
//
// let v = Foo { a: map! { a, "foo".to_string() } };
// let mut d = Decoder::new(Table(map! {
// a, Table(map! {
// a, Value::String("foo".to_string())
// })
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, None);
// }
//
// #[test]
// fn unused_fields5() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: Vec<String> }
//
// let v = Foo { a: vec!["a".to_string()] };
// let mut d = Decoder::new(Table(map! {
// a, Array(vec![Value::String("a".to_string())])
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, None);
// }
//
// #[test]
// fn unused_fields6() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: Option<Vec<String>> }
//
// let v = Foo { a: Some(vec![]) };
// let mut d = Decoder::new(Table(map! {
// a, Array(vec![])
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, None);
// }
//
// #[test]
// fn unused_fields7() {
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Foo { a: Vec<Bar> }
// #[derive(Serialize, Deserialize, PartialEq, Debug)]
// struct Bar { a: isize }
//
// let v = Foo { a: vec![Bar { a: 1 }] };
// let mut d = Decoder::new(Table(map! {
// a, Array(vec![Table(map! {
// a, Integer(1),
// b, Integer(2)
// })])
// }));
// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
//
// assert_eq!(d.toml, Some(Table(map! {
// a, Array(vec![Table(map! {
// b, Integer(2)
// })])
// })));
// }
#[test]
fn empty_arrays() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Vec<Bar> }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar;
equivalent! {
Foo { a: vec![] },
Table(map! {a: Array(Vec::new())}),
}
}
#[test]
fn empty_arrays2() {
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Foo { a: Option<Vec<Bar>> }
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
struct Bar;
equivalent! {
Foo { a: None },
Table(map! {}),
}
equivalent!{
Foo { a: Some(vec![]) },
Table(map! { a: Array(vec![]) }),
}
}
#[test]
fn extra_keys() {
#[derive(Serialize, Deserialize)]
struct Foo { a: isize }
let toml = Table(map! { a: Integer(2), b: Integer(2) });
assert!(toml.clone().try_into::<Foo>().is_ok());
assert!(toml::from_str::<Foo>(&toml.to_string()).is_ok());
}
#[test]
fn newtypes() {
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct A {
b: B
}
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct B(u32);
equivalent! {
A { b: B(2) },
Table(map! { b: Integer(2) }),
}
}
#[test]
fn newtypes2() {
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct A {
b: B
}
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct B(Option<C>);
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
struct C {
x: u32,
y: u32,
z: u32
}
equivalent! {
A { b: B(Some(C { x: 0, y: 1, z: 2 })) },
Table(map! {
b: Table(map! {
x: Integer(0),
y: Integer(1),
z: Integer(2)
})
}),
}
}
#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
struct CanBeEmpty {
a: Option<String>,
b: Option<String>,
}
#[test]
fn table_structs_empty() {
let text = "[bar]\n\n[baz]\n\n[bazv]\na = \"foo\"\n\n[foo]\n";
let value: BTreeMap<String, CanBeEmpty> = toml::from_str(text).unwrap();
let mut expected: BTreeMap<String, CanBeEmpty> = BTreeMap::new();
expected.insert("bar".to_string(), CanBeEmpty::default());
expected.insert("baz".to_string(), CanBeEmpty::default());
expected.insert(
"bazv".to_string(),
CanBeEmpty {a: Some("foo".to_string()), b: None},
);
expected.insert("foo".to_string(), CanBeEmpty::default());
assert_eq!(value, expected);
assert_eq!(toml::to_string(&value).unwrap(), text);
}

30
third_party/rust/toml/tests/tables-last.rs поставляемый
Просмотреть файл

@ -1,30 +0,0 @@
#[macro_use]
extern crate serde_derive;
extern crate toml;
use std::collections::HashMap;
#[derive(Serialize)]
struct A {
#[serde(serialize_with = "toml::ser::tables_last")]
vals: HashMap<&'static str, Value>,
}
#[derive(Serialize)]
#[serde(untagged)]
enum Value {
Map(HashMap<&'static str, &'static str>),
Int(i32),
}
#[test]
fn always_works() {
let mut a = A { vals: HashMap::new() };
a.vals.insert("foo", Value::Int(0));
let mut sub = HashMap::new();
sub.insert("foo", "bar");
a.vals.insert("bar", Value::Map(sub));
toml::to_string(&a).unwrap();
}

130
third_party/rust/toml/tests/valid.rs поставляемый
Просмотреть файл

@ -1,106 +1,65 @@
extern crate rustc_serialize;
extern crate toml;
extern crate serde;
extern crate serde_json;
use toml::{Value as Toml, to_string_pretty};
use serde::ser::Serialize;
use serde_json::Value as Json;
use std::collections::BTreeMap;
use rustc_serialize::json::Json;
fn to_json(toml: toml::Value) -> Json {
use toml::{Parser, Value};
use toml::Value::{Table, Integer, Float, Boolean, Datetime, Array};
fn to_json(toml: Value) -> Json {
fn doit(s: &str, json: Json) -> Json {
let mut map = serde_json::Map::new();
map.insert("type".to_string(), Json::String(s.to_string()));
map.insert("value".to_string(), json);
let mut map = BTreeMap::new();
map.insert(format!("{}", "type"), Json::String(format!("{}", s)));
map.insert(format!("{}", "value"), json);
Json::Object(map)
}
match toml {
Toml::String(s) => doit("string", Json::String(s)),
Toml::Integer(i) => doit("integer", Json::String(i.to_string())),
Toml::Float(f) => doit("float", Json::String({
Value::String(s) => doit("string", Json::String(s)),
Integer(i) => doit("integer", Json::String(format!("{}", i))),
Float(f) => doit("float", Json::String({
let s = format!("{:.15}", f);
let s = format!("{}", s.trim_right_matches('0'));
if s.ends_with('.') {format!("{}0", s)} else {s}
if s.ends_with(".") {format!("{}0", s)} else {s}
})),
Toml::Boolean(b) => doit("bool", Json::String(format!("{}", b))),
Toml::Datetime(s) => doit("datetime", Json::String(s.to_string())),
Toml::Array(arr) => {
Boolean(b) => doit("bool", Json::String(format!("{}", b))),
Datetime(s) => doit("datetime", Json::String(s)),
Array(arr) => {
let is_table = match arr.first() {
Some(&Toml::Table(..)) => true,
Some(&Table(..)) => true,
_ => false,
};
let json = Json::Array(arr.into_iter().map(to_json).collect());
if is_table {json} else {doit("array", json)}
}
Toml::Table(table) => {
let mut map = serde_json::Map::new();
for (k, v) in table {
map.insert(k, to_json(v));
}
Json::Object(map)
}
Table(table) => Json::Object(table.into_iter().map(|(k, v)| {
(k, to_json(v))
}).collect()),
}
}
fn run_pretty(toml: Toml) {
// Assert toml == json
println!("### pretty round trip parse.");
// standard pretty
let toml_raw = to_string_pretty(&toml).expect("to string");
let toml2 = toml_raw.parse().expect("from string");
assert_eq!(toml, toml2);
fn run(toml: &str, json: &str) {
let mut p = Parser::new(toml);
let table = p.parse();
assert!(p.errors.len() == 0, "had_errors: {:?}",
p.errors.iter().map(|e| {
(e.desc.clone(), &toml[e.lo - 5..e.hi + 5])
}).collect::<Vec<(String, &str)>>());
assert!(table.is_some());
let toml = Table(table.unwrap());
let toml_string = format!("{}", toml);
// pretty with indent 2
let mut result = String::with_capacity(128);
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_array_indent(2);
toml.serialize(&mut serializer).expect("to string");
}
assert_eq!(toml, result.parse().expect("from str"));
result.clear();
{
let mut serializer = toml::Serializer::new(&mut result);
serializer.pretty_array_trailing_comma(false);
toml.serialize(&mut serializer).expect("to string");
}
assert_eq!(toml, result.parse().expect("from str"));
result.clear();
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_string(false);
toml.serialize(&mut serializer).expect("to string");
assert_eq!(toml, toml2);
}
assert_eq!(toml, result.parse().expect("from str"));
result.clear();
{
let mut serializer = toml::Serializer::pretty(&mut result);
serializer.pretty_array(false);
toml.serialize(&mut serializer).expect("to string");
assert_eq!(toml, toml2);
}
assert_eq!(toml, result.parse().expect("from str"));
}
fn run(toml_raw: &str, json_raw: &str) {
println!("parsing:\n{}", toml_raw);
let toml: Toml = toml_raw.parse().unwrap();
let json: Json = json_raw.parse().unwrap();
// Assert toml == json
let json = Json::from_str(json).unwrap();
let toml_json = to_json(toml.clone());
assert!(json == toml_json,
"expected\n{}\ngot\n{}\n",
serde_json::to_string_pretty(&json).unwrap(),
serde_json::to_string_pretty(&toml_json).unwrap());
json.pretty(),
toml_json.pretty());
// Assert round trip
println!("round trip parse: {}", toml);
let toml2 = toml.to_string().parse().unwrap();
assert_eq!(toml, toml2);
run_pretty(toml);
let table2 = Parser::new(&toml_string).parse().unwrap();
// floats are a little lossy
if table2.values().any(|v| v.as_float().is_some()) { return }
assert_eq!(toml, Table(table2));
}
macro_rules! test( ($name:ident, $toml:expr, $json:expr) => (
@ -207,9 +166,6 @@ test!(table_empty,
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"));
@ -237,13 +193,3 @@ test!(example4,
test!(example_bom,
include_str!("valid/example-bom.toml"),
include_str!("valid/example.json"));
test!(datetime_truncate,
include_str!("valid/datetime-truncate.toml"),
include_str!("valid/datetime-truncate.json"));
test!(key_quote_newline,
include_str!("valid/key-quote-newline.toml"),
include_str!("valid/key-quote-newline.json"));
test!(table_array_nest_no_keys,
include_str!("valid/table-array-nest-no-keys.toml"),
include_str!("valid/table-array-nest-no-keys.json"));

Просмотреть файл

@ -1,6 +0,0 @@
{
"bestdayever": {
"type": "datetime",
"value": "1987-07-05T17:45:00.123456789Z"
}
}

Просмотреть файл

@ -1 +0,0 @@
bestdayever = 1987-07-05T17:45:00.123456789012345Z

Просмотреть файл

@ -1,3 +0,0 @@
{
"\n": {"type": "integer", "value": "1"}
}

Просмотреть файл

@ -1 +0,0 @@
"\n" = 1

Просмотреть файл

@ -1,14 +0,0 @@
{
"albums": [
{
"songs": [{}, {}]
}
],
"artists": [
{
"home": {
"address": {}
}
}
]
}

Просмотреть файл

@ -1,6 +0,0 @@
[[ albums ]]
[[ albums.songs ]]
[[ albums.songs ]]
[[ artists ]]
[ artists.home.address ]

Просмотреть файл

@ -1,5 +0,0 @@
{
"a": { "b": {} },
"b": {},
"c": { "a": {} }
}

Просмотреть файл

@ -1,5 +0,0 @@
[a]
[a.b]
[b]
[c]
[c.a]

Просмотреть файл

@ -1,5 +1,4 @@
{
"answer1": {"type": "string", "value": "\u000B"},
"answer4": {"type": "string", "value": "\u03B4α"},
"answer8": {"type": "string", "value": "\u03B4β"}
}

Просмотреть файл

@ -1,3 +1,2 @@
answer1 = "\u000B"
answer4 = "\u03B4α"
answer8 = "\U000003B4β"