2014-06-20 19:30:08 -05:00
|
|
|
//! A TOML-parsing library
|
|
|
|
//!
|
|
|
|
//! 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.
|
|
|
|
//!
|
|
|
|
//! This implementation currently passes the language agnostic [test suite][2].
|
|
|
|
//!
|
|
|
|
//! # Example
|
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
//! let toml = r#"
|
|
|
|
//! [test]
|
|
|
|
//! foo = "bar"
|
|
|
|
//! "#;
|
|
|
|
//!
|
|
|
|
//! let value = toml::Parser::new(toml).parse().unwrap();
|
2015-01-07 10:58:50 -06:00
|
|
|
//! println!("{:?}", value);
|
2014-06-20 19:30:08 -05:00
|
|
|
//! ```
|
|
|
|
//!
|
2014-06-22 01:35:49 -05:00
|
|
|
//! # Conversions
|
|
|
|
//!
|
|
|
|
//! This library also supports using the standard `Encodable` and `Decodable`
|
|
|
|
//! traits with TOML values. This library provides the following conversion
|
|
|
|
//! capabilities:
|
|
|
|
//!
|
|
|
|
//! * `String` => `toml::Value` - via `Parser`
|
2015-02-03 00:29:51 -06:00
|
|
|
//! * `toml::Value` => `String` - via `Display`
|
2014-06-22 01:35:49 -05:00
|
|
|
//! * `toml::Value` => rust object - via `Decoder`
|
|
|
|
//! * rust object => `toml::Value` - via `Encoder`
|
|
|
|
//!
|
|
|
|
//! Convenience functions for performing multiple conversions at a time are also
|
|
|
|
//! provided.
|
|
|
|
//!
|
2014-06-20 19:30:08 -05:00
|
|
|
//! [1]: https://github.com/mojombo/toml
|
|
|
|
//! [2]: https://github.com/BurntSushi/toml-test
|
2017-01-09 19:37:05 -06:00
|
|
|
//!
|
|
|
|
//! # Encoding support
|
|
|
|
//!
|
|
|
|
//! This crate optionally supports the [`rustc-serialize`] crate and also the
|
|
|
|
//! [`serde`] crate through respective feature names. The `rustc-serialize`
|
|
|
|
//! feature is enabled by default.
|
|
|
|
//!
|
|
|
|
//! [`rustc-serialize`]: http://github.com/rust-lang/rustc-serialize
|
|
|
|
//! [`serde`]: http://github.com/serde-rs/serde
|
2015-03-03 22:35:04 -06:00
|
|
|
|
2015-03-03 19:27:09 -06:00
|
|
|
#![doc(html_root_url = "http://alexcrichton.com/toml-rs")]
|
2014-10-31 10:27:24 -05:00
|
|
|
#![deny(missing_docs)]
|
2014-12-23 10:01:35 -06:00
|
|
|
#![cfg_attr(test, deny(warnings))]
|
2014-06-22 01:35:49 -05:00
|
|
|
|
2015-04-02 19:04:17 -05:00
|
|
|
#[cfg(feature = "rustc-serialize")] extern crate rustc_serialize;
|
2015-04-02 19:07:26 -05:00
|
|
|
#[cfg(feature = "serde")] extern crate serde;
|
2014-06-20 19:01:38 -05:00
|
|
|
|
2014-12-21 00:35:14 -06:00
|
|
|
use std::collections::BTreeMap;
|
2014-11-17 02:48:33 -06:00
|
|
|
use std::str::FromStr;
|
2014-06-20 19:01:38 -05:00
|
|
|
|
2014-11-04 13:56:11 -06:00
|
|
|
pub use parser::{Parser, ParserError};
|
2015-04-02 19:04:17 -05:00
|
|
|
|
|
|
|
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
|
2016-07-29 12:23:06 -05:00
|
|
|
pub use self::encoder::{Encoder, Error, EncoderState, encode, encode_str};
|
2015-04-02 19:04:17 -05:00
|
|
|
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
|
|
|
|
pub use self::decoder::{Decoder, DecodeError, DecodeErrorKind, decode, decode_str};
|
2014-11-18 02:13:21 -06:00
|
|
|
|
2014-06-20 19:01:38 -05:00
|
|
|
mod parser;
|
2015-02-03 00:30:06 -06:00
|
|
|
mod display;
|
2015-04-02 19:04:17 -05:00
|
|
|
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
|
|
|
|
mod encoder;
|
|
|
|
#[cfg(any(feature = "rustc-serialize", feature = "serde"))]
|
|
|
|
mod decoder;
|
2015-01-15 14:44:05 -06:00
|
|
|
|
2014-06-20 19:30:08 -05:00
|
|
|
/// Representation of a TOML value.
|
2015-02-03 00:29:51 -06:00
|
|
|
#[derive(PartialEq, Clone, Debug)]
|
2014-10-31 10:27:24 -05:00
|
|
|
#[allow(missing_docs)]
|
2014-06-20 19:01:38 -05:00
|
|
|
pub enum Value {
|
2015-03-20 12:53:21 -05:00
|
|
|
String(String),
|
2014-06-20 19:01:38 -05:00
|
|
|
Integer(i64),
|
|
|
|
Float(f64),
|
|
|
|
Boolean(bool),
|
2015-03-20 12:53:21 -05:00
|
|
|
Datetime(String),
|
2014-12-06 16:51:51 -06:00
|
|
|
Array(Array),
|
|
|
|
Table(Table),
|
2014-06-20 19:01:38 -05:00
|
|
|
}
|
|
|
|
|
2016-06-03 21:14:42 -05:00
|
|
|
/// Type representing a TOML array, payload of the `Value::Array` variant
|
2014-12-06 16:48:32 -06:00
|
|
|
pub type Array = Vec<Value>;
|
|
|
|
|
2016-06-03 21:14:42 -05:00
|
|
|
/// Type representing a TOML table, payload of the `Value::Table` variant
|
2015-08-11 11:18:52 -05:00
|
|
|
pub type Table = BTreeMap<String, Value>;
|
2014-06-20 19:01:38 -05:00
|
|
|
|
|
|
|
impl Value {
|
2014-06-20 19:30:08 -05:00
|
|
|
/// Tests whether this and another value have the same type.
|
|
|
|
pub fn same_type(&self, other: &Value) -> bool {
|
2014-06-20 19:01:38 -05:00
|
|
|
match (self, other) {
|
2014-12-06 16:51:51 -06:00
|
|
|
(&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,
|
2014-06-20 19:01:38 -05:00
|
|
|
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-20 19:30:08 -05:00
|
|
|
/// Returns a human-readable representation of the type of this value.
|
|
|
|
pub fn type_str(&self) -> &'static str {
|
2014-06-20 19:01:38 -05:00
|
|
|
match *self {
|
2014-12-06 16:51:51 -06:00
|
|
|
Value::String(..) => "string",
|
|
|
|
Value::Integer(..) => "integer",
|
|
|
|
Value::Float(..) => "float",
|
|
|
|
Value::Boolean(..) => "boolean",
|
|
|
|
Value::Datetime(..) => "datetime",
|
|
|
|
Value::Array(..) => "array",
|
|
|
|
Value::Table(..) => "table",
|
2014-06-20 19:01:38 -05:00
|
|
|
}
|
|
|
|
}
|
2014-06-20 19:30:08 -05:00
|
|
|
|
|
|
|
/// Extracts the string of this value if it is a string.
|
2016-01-20 22:30:45 -06:00
|
|
|
pub fn as_str(&self) -> Option<&str> {
|
2015-01-27 21:29:58 -06:00
|
|
|
match *self { Value::String(ref s) => Some(&**s), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extracts the integer value if it is an integer.
|
|
|
|
pub fn as_integer(&self) -> Option<i64> {
|
2014-12-06 16:51:51 -06:00
|
|
|
match *self { Value::Integer(i) => Some(i), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extracts the float value if it is a float.
|
|
|
|
pub fn as_float(&self) -> Option<f64> {
|
2014-12-06 16:51:51 -06:00
|
|
|
match *self { Value::Float(f) => Some(f), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extracts the boolean value if it is a boolean.
|
|
|
|
pub fn as_bool(&self) -> Option<bool> {
|
2014-12-06 16:51:51 -06:00
|
|
|
match *self { Value::Boolean(b) => Some(b), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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
|
|
|
|
/// ```
|
2016-01-20 22:30:45 -06:00
|
|
|
pub fn as_datetime(&self) -> Option<&str> {
|
2015-01-27 21:29:58 -06:00
|
|
|
match *self { Value::Datetime(ref s) => Some(&**s), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extracts the array value if it is an array.
|
2016-01-20 22:30:45 -06:00
|
|
|
pub fn as_slice(&self) -> Option<&[Value]> {
|
2015-01-27 21:29:58 -06:00
|
|
|
match *self { Value::Array(ref s) => Some(&**s), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Extracts the table value if it is a table.
|
2016-01-20 22:30:45 -06:00
|
|
|
pub fn as_table(&self) -> Option<&Table> {
|
2014-12-06 16:51:51 -06:00
|
|
|
match *self { Value::Table(ref s) => Some(s), _ => None }
|
2014-06-20 19:30:08 -05:00
|
|
|
}
|
2014-06-25 04:22:11 -05:00
|
|
|
|
|
|
|
/// Lookups for value at specified path.
|
|
|
|
///
|
|
|
|
/// Uses '.' as a path separator.
|
|
|
|
///
|
|
|
|
/// Note: arrays have zero-based indexes.
|
2014-06-25 09:00:10 -05:00
|
|
|
///
|
2015-09-25 11:26:47 -05:00
|
|
|
/// Note: empty path returns self.
|
|
|
|
///
|
2014-06-25 09:00:10 -05:00
|
|
|
/// ```
|
2015-01-09 13:48:06 -06:00
|
|
|
/// # #![allow(unstable)]
|
2014-06-25 09:00:10 -05:00
|
|
|
/// let toml = r#"
|
|
|
|
/// [test]
|
|
|
|
/// foo = "bar"
|
|
|
|
///
|
|
|
|
/// [[values]]
|
|
|
|
/// foo = "baz"
|
|
|
|
///
|
|
|
|
/// [[values]]
|
|
|
|
/// foo = "qux"
|
|
|
|
/// "#;
|
2014-12-23 10:01:35 -06:00
|
|
|
/// let value: toml::Value = toml.parse().unwrap();
|
2014-06-25 09:00:10 -05:00
|
|
|
///
|
|
|
|
/// 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);
|
|
|
|
/// ```
|
2016-06-03 21:14:42 -05:00
|
|
|
pub fn lookup(&self, path: &str) -> Option<&Value> {
|
2016-03-27 13:46:19 -05:00
|
|
|
let ref path = match Parser::new(path).lookup() {
|
|
|
|
Some(path) => path,
|
|
|
|
None => return None,
|
|
|
|
};
|
2014-06-27 09:28:55 -05:00
|
|
|
let mut cur_value = self;
|
2016-06-03 21:14:42 -05:00
|
|
|
if path.is_empty() {
|
2015-09-25 11:26:47 -05:00
|
|
|
return Some(cur_value)
|
|
|
|
}
|
|
|
|
|
2016-03-27 13:46:19 -05:00
|
|
|
for key in path {
|
2016-01-20 22:30:45 -06:00
|
|
|
match *cur_value {
|
|
|
|
Value::Table(ref hm) => {
|
2014-12-21 00:35:14 -06:00
|
|
|
match hm.get(key) {
|
2014-06-25 04:22:11 -05:00
|
|
|
Some(v) => cur_value = v,
|
2014-12-21 00:35:14 -06:00
|
|
|
None => return None
|
2014-06-25 04:22:11 -05:00
|
|
|
}
|
|
|
|
},
|
2016-01-20 22:30:45 -06:00
|
|
|
Value::Array(ref v) => {
|
2015-02-03 10:37:05 -06:00
|
|
|
match key.parse::<usize>().ok() {
|
2014-07-17 05:52:05 -05:00
|
|
|
Some(idx) if idx < v.len() => cur_value = &v[idx],
|
2014-06-25 04:22:11 -05:00
|
|
|
_ => return None
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_ => return None
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Some(cur_value)
|
2016-03-24 08:18:00 -05:00
|
|
|
|
2016-03-27 13:46:19 -05:00
|
|
|
}
|
2016-03-24 08:18:00 -05:00
|
|
|
/// 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");
|
|
|
|
/// ```
|
2016-03-25 11:33:46 -05:00
|
|
|
pub fn lookup_mut(&mut self, path: &str) -> Option<&mut Value> {
|
2016-03-27 13:48:23 -05:00
|
|
|
let ref path = match Parser::new(path).lookup() {
|
|
|
|
Some(path) => path,
|
|
|
|
None => return None,
|
|
|
|
};
|
|
|
|
|
2016-03-25 11:33:46 -05:00
|
|
|
let mut cur = self;
|
2016-06-03 21:14:42 -05:00
|
|
|
if path.is_empty() {
|
2016-03-25 11:33:46 -05:00
|
|
|
return Some(cur)
|
|
|
|
}
|
2016-03-24 08:18:00 -05:00
|
|
|
|
2016-03-27 13:48:23 -05:00
|
|
|
for key in path {
|
2016-03-25 11:33:46 -05:00
|
|
|
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)
|
|
|
|
}
|
2014-06-20 19:01:38 -05:00
|
|
|
}
|
2014-06-22 01:35:49 -05:00
|
|
|
|
|
|
|
impl FromStr for Value {
|
2015-02-03 10:37:05 -06:00
|
|
|
type Err = Vec<ParserError>;
|
|
|
|
fn from_str(s: &str) -> Result<Value, Vec<ParserError>> {
|
|
|
|
let mut p = Parser::new(s);
|
2015-03-09 13:09:07 -05:00
|
|
|
match p.parse().map(Value::Table) {
|
|
|
|
Some(n) => Ok(n),
|
|
|
|
None => Err(p.errors),
|
|
|
|
}
|
2014-06-22 01:35:49 -05:00
|
|
|
}
|
|
|
|
}
|
2014-06-25 09:00:10 -05:00
|
|
|
|
|
|
|
#[cfg(test)]
|
2014-06-27 09:28:55 -05:00
|
|
|
mod tests {
|
2014-06-25 09:00:10 -05:00
|
|
|
use super::Value;
|
|
|
|
|
2016-03-25 11:43:32 -05:00
|
|
|
#[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");
|
|
|
|
}
|
|
|
|
|
2016-03-25 11:33:46 -05:00
|
|
|
#[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");
|
|
|
|
}
|
|
|
|
|
2014-06-25 09:00:10 -05:00
|
|
|
#[test]
|
|
|
|
fn lookup_valid() {
|
|
|
|
let toml = r#"
|
|
|
|
[test]
|
|
|
|
foo = "bar"
|
|
|
|
|
|
|
|
[[values]]
|
|
|
|
foo = "baz"
|
|
|
|
|
|
|
|
[[values]]
|
|
|
|
foo = "qux"
|
|
|
|
"#;
|
|
|
|
|
2014-12-23 10:01:35 -06:00
|
|
|
let value: Value = toml.parse().unwrap();
|
2014-06-25 09:00:10 -05:00
|
|
|
|
|
|
|
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");
|
|
|
|
|
2015-03-15 13:26:32 -05:00
|
|
|
assert!(value.lookup("test.bar").is_none());
|
|
|
|
assert!(value.lookup("test.foo.bar").is_none());
|
2014-06-25 09:00:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn lookup_invalid_index() {
|
|
|
|
let toml = r#"
|
|
|
|
[[values]]
|
|
|
|
foo = "baz"
|
|
|
|
"#;
|
|
|
|
|
2014-12-23 10:01:35 -06:00
|
|
|
let value: Value = toml.parse().unwrap();
|
2014-06-25 09:00:10 -05:00
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
2015-09-25 11:26:47 -05:00
|
|
|
|
|
|
|
#[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");
|
|
|
|
}
|
2016-03-27 13:46:19 -05:00
|
|
|
|
|
|
|
#[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));
|
|
|
|
}
|
|
|
|
|
2016-03-27 14:19:03 -05:00
|
|
|
#[test]
|
|
|
|
fn lookup_advanced_table() {
|
2016-04-17 16:51:43 -05:00
|
|
|
let value: Value = "[table.\"name.other\"]\nvalue = \"my value\"".parse().unwrap();
|
2016-03-27 13:55:49 -05:00
|
|
|
let looked = value.lookup(r#"table."name.other".value"#).unwrap();
|
|
|
|
assert_eq!(*looked, Value::String(String::from("my value")));
|
2016-03-27 14:19:03 -05:00
|
|
|
}
|
2016-03-27 13:55:49 -05:00
|
|
|
|
2016-03-27 13:50:25 -05:00
|
|
|
#[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));
|
|
|
|
}
|
|
|
|
|
2016-03-27 23:35:39 -05:00
|
|
|
#[test]
|
|
|
|
fn single_dot() {
|
|
|
|
let value: Value = "[table]\n\"value\" = [0, 1, 2]".parse().unwrap();
|
|
|
|
assert_eq!(None, value.lookup("."));
|
|
|
|
}
|
2016-03-27 13:50:25 -05:00
|
|
|
|
2016-03-27 23:35:39 -05:00
|
|
|
#[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());
|
|
|
|
}
|
2016-03-27 13:50:25 -05:00
|
|
|
|
2016-12-30 19:34:11 -06:00
|
|
|
#[test]
|
|
|
|
fn control_characters() {
|
|
|
|
let value = Value::String("\x05".to_string());
|
|
|
|
assert_eq!(value.to_string(), r#""\u0005""#);
|
|
|
|
}
|
|
|
|
|
2014-06-25 09:00:10 -05:00
|
|
|
}
|