From 934e093047ae15432fcc772d4e01fdf5fd56d2fb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 3 Aug 2014 21:30:30 -0700 Subject: Put documentation on github --- .travis.yml | 18 +++-- Cargo.toml | 8 +- README.md | 14 ++++ src/lib.rs | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/toml.rs | 252 ------------------------------------------------------------ 5 files changed, 280 insertions(+), 264 deletions(-) create mode 100644 README.md create mode 100644 src/lib.rs delete mode 100644 src/toml.rs diff --git a/.travis.yml b/.travis.yml index b92cce0..68735e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,15 @@ install: - - curl http://www.rust-lang.org/rustup.sh | sudo sh - +- curl http://www.rust-lang.org/rustup.sh | sudo sh - script: - - make - - make check - - cargo build --verbose - - cargo test --verbose +- cargo build --verbose +- cargo test --verbose +- rustdoc --test src/lib.rs -L target --crate-name toml +- cargo doc +after_success: ! '[ $TRAVIS_BRANCH = master ] && [ $TRAVIS_PULL_REQUEST = false ] + && echo '''' > target/doc/index.html + && sudo pip install ghp-import && ghp-import -n target/doc && git push -fq https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git + gh-pages ' env: - - LD_LIBRARY_PATH=/usr/local/lib + global: + - LD_LIBRARY_PATH: /usr/local/lib + - secure: bK8RmAtQcJvxXZFe+WqfRwuQqq1h3PXCFtrd73m4PWysdMEhtWb+ZKugPw8ykT3YVVLqbLnzH2Z8iM0RkF57aJvk7H1P4Syw4h2pPvvgP91ayzHbUnWwxkkJJ+oQ8lDJtcDHQ4BQhKMpTqY4tbaG6KeSwSdqDRCJuzHbZJzR0Eg= diff --git a/Cargo.toml b/Cargo.toml index 577a45d..fc6861b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,5 @@ -[project] +[package] name = "toml" version = "0.1.0" -authors = ["alex@crichton.co"] - -[[lib]] - -name = "toml" +authors = ["Alex Crichton "] diff --git a/README.md b/README.md new file mode 100644 index 0000000..86043c3 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# toml-rs + +[![Build Status](https://travis-ci.org/alexcrichton/toml-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/toml-rs) + +[Documentation](http://alexcrichton.com/toml-rs/toml/index.html) + +A TOML decoder and encoder for Rust. + +```toml +# Cargo.toml +[dependencies.toml] +git = "https://github.com/alexcrichton/toml-rs" +``` + diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d768b7c --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,252 @@ +//! 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(); +//! println!("{}", value); +//! ``` +//! +//! # 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` +//! * `toml::Value` => `String` - via `Show` +//! * `toml::Value` => rust object - via `Decoder` +//! * rust object => `toml::Value` - via `Encoder` +//! +//! Convenience functions for performing multiple conversions at a time are also +//! provided. +//! +//! [1]: https://github.com/mojombo/toml +//! [2]: https://github.com/BurntSushi/toml-test +//! + +#![crate_type = "lib"] +#![feature(macro_rules)] +#![deny(warnings, missing_doc)] +#![allow(visible_private_types)] + +extern crate serialize; + +use std::collections::TreeMap; +use std::from_str::FromStr; + +pub use parser::{Parser, Error}; +pub use serialization::{Encoder, encode, encode_str}; +pub use serialization::{Decoder, decode, decode_str}; +pub use serialization::{Error, NeedsKey, NoValue}; +pub use serialization::{InvalidMapKeyLocation, InvalidMapKeyType}; + +mod parser; +mod show; +mod serialization; +#[cfg(test)]mod test; +/// Representation of a TOML value. +#[deriving(PartialEq, Clone)] +#[allow(missing_doc)] +pub enum Value { + String(String), + Integer(i64), + Float(f64), + Boolean(bool), + Datetime(String), + Array(Array), + Table(Table), +} + +pub type Array = Vec; +pub type Table = TreeMap; + +impl Value { + /// Tests whether this and another value have the same type. + pub fn same_type(&self, other: &Value) -> bool { + match (self, other) { + (&String(..), &String(..)) | + (&Integer(..), &Integer(..)) | + (&Float(..), &Float(..)) | + (&Boolean(..), &Boolean(..)) | + (&Datetime(..), &Datetime(..)) | + (&Array(..), &Array(..)) | + (&Table(..), &Table(..)) => true, + + _ => false, + } + } + + /// Returns a human-readable representation of the type of this value. + pub fn type_str(&self) -> &'static str { + match *self { + String(..) => "string", + Integer(..) => "integer", + Float(..) => "float", + Boolean(..) => "boolean", + Datetime(..) => "datetime", + Array(..) => "array", + Table(..) => "table", + } + } + + /// Extracts the string of this value if it is a string. + pub fn as_str<'a>(&'a self) -> Option<&'a str> { + match *self { String(ref s) => Some(s.as_slice()), _ => None } + } + + /// Extracts the integer value if it is an integer. + pub fn as_integer(&self) -> Option { + match *self { Integer(i) => Some(i), _ => None } + } + + /// Extracts the float value if it is a float. + pub fn as_float(&self) -> Option { + match *self { Float(f) => Some(f), _ => None } + } + + /// Extracts the boolean value if it is a boolean. + pub fn as_bool(&self) -> Option { + match *self { 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<'a>(&'a self) -> Option<&'a str> { + match *self { Datetime(ref s) => Some(s.as_slice()), _ => None } + } + + /// Extracts the array value if it is an array. + pub fn as_slice<'a>(&'a self) -> Option<&'a [Value]> { + match *self { Array(ref s) => Some(s.as_slice()), _ => None } + } + + /// Extracts the table value if it is a table. + pub fn as_table<'a>(&'a self) -> Option<&'a Table> { + match *self { Table(ref s) => Some(s), _ => None } + } + + /// Lookups for value at specified path. + /// + /// Uses '.' as a path separator. + /// + /// Note: arrays have zero-based indexes. + /// + /// ``` + /// let toml = r#" + /// [test] + /// foo = "bar" + /// + /// [[values]] + /// foo = "baz" + /// + /// [[values]] + /// foo = "qux" + /// "#; + /// let value: toml::Value = from_str(toml).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<'a>(&'a self, path: &'a str) -> Option<&'a Value> { + let mut cur_value = self; + for key in path.split('.') { + match cur_value { + &Table(ref hm) => { + match hm.find_with(|k| key.cmp(&k.as_slice())) { + Some(v) => cur_value = v, + _ => return None + } + }, + &Array(ref v) => { + let idx: Option = FromStr::from_str(key); + match idx { + Some(idx) if idx < v.len() => cur_value = &v[idx], + _ => return None + } + }, + _ => return None + } + }; + + Some(cur_value) + } +} + +impl FromStr for Value { + fn from_str(s: &str) -> Option { + Parser::new(s).parse().map(Table) + } +} + +#[cfg(test)] +mod tests { + use super::Value; + + #[test] + fn lookup_valid() { + let toml = r#" + [test] + foo = "bar" + + [[values]] + foo = "baz" + + [[values]] + foo = "qux" + "#; + + let value: Value = from_str(toml).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"); + + let no_bar = value.lookup("test.bar"); + assert!(no_bar.is_none()); + } + + #[test] + fn lookup_invalid_index() { + let toml = r#" + [[values]] + foo = "baz" + "#; + + let value: Value = from_str(toml).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()); + } +} diff --git a/src/toml.rs b/src/toml.rs deleted file mode 100644 index d768b7c..0000000 --- a/src/toml.rs +++ /dev/null @@ -1,252 +0,0 @@ -//! 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(); -//! println!("{}", value); -//! ``` -//! -//! # 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` -//! * `toml::Value` => `String` - via `Show` -//! * `toml::Value` => rust object - via `Decoder` -//! * rust object => `toml::Value` - via `Encoder` -//! -//! Convenience functions for performing multiple conversions at a time are also -//! provided. -//! -//! [1]: https://github.com/mojombo/toml -//! [2]: https://github.com/BurntSushi/toml-test -//! - -#![crate_type = "lib"] -#![feature(macro_rules)] -#![deny(warnings, missing_doc)] -#![allow(visible_private_types)] - -extern crate serialize; - -use std::collections::TreeMap; -use std::from_str::FromStr; - -pub use parser::{Parser, Error}; -pub use serialization::{Encoder, encode, encode_str}; -pub use serialization::{Decoder, decode, decode_str}; -pub use serialization::{Error, NeedsKey, NoValue}; -pub use serialization::{InvalidMapKeyLocation, InvalidMapKeyType}; - -mod parser; -mod show; -mod serialization; -#[cfg(test)]mod test; -/// Representation of a TOML value. -#[deriving(PartialEq, Clone)] -#[allow(missing_doc)] -pub enum Value { - String(String), - Integer(i64), - Float(f64), - Boolean(bool), - Datetime(String), - Array(Array), - Table(Table), -} - -pub type Array = Vec; -pub type Table = TreeMap; - -impl Value { - /// Tests whether this and another value have the same type. - pub fn same_type(&self, other: &Value) -> bool { - match (self, other) { - (&String(..), &String(..)) | - (&Integer(..), &Integer(..)) | - (&Float(..), &Float(..)) | - (&Boolean(..), &Boolean(..)) | - (&Datetime(..), &Datetime(..)) | - (&Array(..), &Array(..)) | - (&Table(..), &Table(..)) => true, - - _ => false, - } - } - - /// Returns a human-readable representation of the type of this value. - pub fn type_str(&self) -> &'static str { - match *self { - String(..) => "string", - Integer(..) => "integer", - Float(..) => "float", - Boolean(..) => "boolean", - Datetime(..) => "datetime", - Array(..) => "array", - Table(..) => "table", - } - } - - /// Extracts the string of this value if it is a string. - pub fn as_str<'a>(&'a self) -> Option<&'a str> { - match *self { String(ref s) => Some(s.as_slice()), _ => None } - } - - /// Extracts the integer value if it is an integer. - pub fn as_integer(&self) -> Option { - match *self { Integer(i) => Some(i), _ => None } - } - - /// Extracts the float value if it is a float. - pub fn as_float(&self) -> Option { - match *self { Float(f) => Some(f), _ => None } - } - - /// Extracts the boolean value if it is a boolean. - pub fn as_bool(&self) -> Option { - match *self { 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<'a>(&'a self) -> Option<&'a str> { - match *self { Datetime(ref s) => Some(s.as_slice()), _ => None } - } - - /// Extracts the array value if it is an array. - pub fn as_slice<'a>(&'a self) -> Option<&'a [Value]> { - match *self { Array(ref s) => Some(s.as_slice()), _ => None } - } - - /// Extracts the table value if it is a table. - pub fn as_table<'a>(&'a self) -> Option<&'a Table> { - match *self { Table(ref s) => Some(s), _ => None } - } - - /// Lookups for value at specified path. - /// - /// Uses '.' as a path separator. - /// - /// Note: arrays have zero-based indexes. - /// - /// ``` - /// let toml = r#" - /// [test] - /// foo = "bar" - /// - /// [[values]] - /// foo = "baz" - /// - /// [[values]] - /// foo = "qux" - /// "#; - /// let value: toml::Value = from_str(toml).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<'a>(&'a self, path: &'a str) -> Option<&'a Value> { - let mut cur_value = self; - for key in path.split('.') { - match cur_value { - &Table(ref hm) => { - match hm.find_with(|k| key.cmp(&k.as_slice())) { - Some(v) => cur_value = v, - _ => return None - } - }, - &Array(ref v) => { - let idx: Option = FromStr::from_str(key); - match idx { - Some(idx) if idx < v.len() => cur_value = &v[idx], - _ => return None - } - }, - _ => return None - } - }; - - Some(cur_value) - } -} - -impl FromStr for Value { - fn from_str(s: &str) -> Option { - Parser::new(s).parse().map(Table) - } -} - -#[cfg(test)] -mod tests { - use super::Value; - - #[test] - fn lookup_valid() { - let toml = r#" - [test] - foo = "bar" - - [[values]] - foo = "baz" - - [[values]] - foo = "qux" - "#; - - let value: Value = from_str(toml).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"); - - let no_bar = value.lookup("test.bar"); - assert!(no_bar.is_none()); - } - - #[test] - fn lookup_invalid_index() { - let toml = r#" - [[values]] - foo = "baz" - "#; - - let value: Value = from_str(toml).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()); - } -} -- cgit v1.2.3