--- a/third_party/rust/rust-ini/src/ini.rs
+++ b/third_party/rust/rust-ini/src/ini.rs
@@ -17,22 +17,22 @@
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//! Ini
use std::collections::HashMap;
-use std::collections::hash_map::{Iter, IterMut, IntoIter, Keys};
+use std::collections::hash_map::{IntoIter, Iter, IterMut, Keys};
use std::collections::hash_map::Entry;
-use std::fs::{OpenOptions, File};
+use std::fs::{File, OpenOptions};
use std::ops::{Index, IndexMut};
use std::char;
-use std::io::{self, Write, Read};
+use std::io::{self, Read, Write};
use std::fmt::{self, Display};
use std::path::Path;
use std::str::Chars;
use std::borrow::Borrow;
use std::hash::Hash;
use std::cmp::Eq;
use std::error;
@@ -77,19 +77,17 @@ impl EscapePolicy {
_ => false,
}
}
/// Given a character this returns true if it should be escaped as
/// per this policy or false if not.
pub fn should_escape(&self, c: char) -> bool {
match c {
- '\\' |
- '\x00'...'\x1f' |
- '\x7f'...'\u{00ff}' => self.escape_basics(),
+ '\\' | '\x00'...'\x1f' | '\x7f'...'\u{00ff}' => self.escape_basics(),
';' | '#' | '=' | ':' => self.escape_reserved(),
'\u{0080}'...'\u{FFFF}' => self.escape_unicode(),
_ => false,
}
}
}
// Escape non-INI characters
@@ -116,19 +114,19 @@ fn escape_str(s: &str, policy: EscapePol
if !policy.should_escape(c) {
escaped.push(c);
continue;
}
match c {
'\\' => escaped.push_str("\\\\"),
'\0' => escaped.push_str("\\0"),
- '\x01'...'\x06' |
- '\x0e'...'\x1f' |
- '\x7f'...'\u{00ff}' => escaped.push_str(&format!("\\x{:04x}", c as isize)[..]),
+ '\x01'...'\x06' | '\x0e'...'\x1f' | '\x7f'...'\u{00ff}' => {
+ escaped.push_str(&format!("\\x{:04x}", c as isize)[..])
+ }
'\x07' => escaped.push_str("\\a"),
'\x08' => escaped.push_str("\\b"),
'\x0c' => escaped.push_str("\\f"),
'\x0b' => escaped.push_str("\\v"),
'\n' => escaped.push_str("\\n"),
'\t' => escaped.push_str("\\t"),
'\r' => escaped.push_str("\\r"),
'\u{0080}'...'\u{FFFF}' => escaped.push_str(&format!("\\x{:04x}", c as isize)[..]),
@@ -152,44 +150,47 @@ impl<'a> SectionSetter<'a> {
SectionSetter {
ini: ini,
section_name: section_name,
}
}
/// Set key-value pair in this section
pub fn set<K, V>(&'a mut self, key: K, value: V) -> &'a mut SectionSetter<'a>
- where K: Into<String>,
- V: Into<String>
+ where
+ K: Into<String>,
+ V: Into<String>,
{
{
let prop = match self.ini.sections.entry(self.section_name.clone()) {
Entry::Vacant(entry) => entry.insert(HashMap::new()),
Entry::Occupied(entry) => entry.into_mut(),
};
prop.insert(key.into(), value.into());
}
self
}
/// Delete the entry in this section with `key`
pub fn delete<K>(&'a mut self, key: &K) -> &'a mut SectionSetter<'a>
- where String: Borrow<K>,
- K: Hash + Eq + ?Sized
+ where
+ String: Borrow<K>,
+ K: Hash + Eq + ?Sized,
{
if let Some(prop) = self.ini.sections.get_mut(&self.section_name) {
prop.remove(key);
}
self
}
/// Get the entry in this section with `key`
pub fn get<K>(&'a mut self, key: &K) -> Option<&'a str>
- where String: Borrow<K>,
- K: Hash + Eq + ?Sized
+ where
+ String: Borrow<K>,
+ K: Hash + Eq + ?Sized,
{
self.ini
.sections
.get(&self.section_name)
.and_then(|prop| prop.get(key).map(|s| &s[..]))
}
}
@@ -200,46 +201,53 @@ pub type Properties = HashMap<String, St
#[derive(Clone)]
pub struct Ini {
sections: HashMap<Option<String>, Properties>,
}
impl Ini {
/// Create an instance
pub fn new() -> Ini {
- Ini { sections: HashMap::new() }
+ Ini {
+ sections: HashMap::new(),
+ }
}
/// Set with a specified section, `None` is for the general section
pub fn with_section<'b, S>(&'b mut self, section: Option<S>) -> SectionSetter<'b>
- where S: Into<String>
+ where
+ S: Into<String>,
{
SectionSetter::new(self, section.map(|s| s.into()))
}
/// Get the immmutable general section
pub fn general_section(&self) -> &Properties {
- self.section(None::<String>).expect("There is no general section in this Ini")
+ self.section(None::<String>)
+ .expect("There is no general section in this Ini")
}
/// Get the mutable general section
pub fn general_section_mut(&mut self) -> &mut Properties {
- self.section_mut(None::<String>).expect("There is no general section in this Ini")
+ self.section_mut(None::<String>)
+ .expect("There is no general section in this Ini")
}
/// Get a immutable section
pub fn section<'a, S>(&'a self, name: Option<S>) -> Option<&'a Properties>
- where S: Into<String>
+ where
+ S: Into<String>,
{
self.sections.get(&name.map(|s| s.into()))
}
/// Get a mutable section
pub fn section_mut<'a, S>(&'a mut self, name: Option<S>) -> Option<&'a mut Properties>
- where S: Into<String>
+ where
+ S: Into<String>,
{
self.sections.get_mut(&name.map(|s| s.into()))
}
/// Get the entry
pub fn entry<'a>(&'a mut self, name: Option<String>) -> Entry<Option<String>, Properties> {
self.sections.entry(name.map(|s| s.into()))
}
@@ -251,88 +259,90 @@ impl Ini {
/// Iterate with sections
pub fn sections<'a>(&'a self) -> Keys<'a, Option<String>, Properties> {
self.sections.keys()
}
/// Set key-value to a section
pub fn set_to<S>(&mut self, section: Option<S>, key: String, value: String)
- where S: Into<String>
+ where
+ S: Into<String>,
{
self.with_section(section).set(key, value);
}
/// Get the value from a section with key
///
/// Example:
///
/// ```
/// use ini::Ini;
/// let input = "[sec]\nabc = def\n";
/// let ini = Ini::load_from_str(input).unwrap();
/// assert_eq!(ini.get_from(Some("sec"), "abc"), Some("def"));
/// ```
pub fn get_from<'a, S>(&'a self, section: Option<S>, key: &str) -> Option<&'a str>
- where S: Into<String>
+ where
+ S: Into<String>,
{
match self.sections.get(§ion.map(|s| s.into())) {
None => None,
- Some(ref prop) => {
- match prop.get(key) {
- Some(p) => Some(&p[..]),
- None => None,
- }
- }
+ Some(ref prop) => match prop.get(key) {
+ Some(p) => Some(&p[..]),
+ None => None,
+ },
}
}
/// Get the value from a section with key, return the default value if it does not exist
///
/// Example:
///
/// ```
/// use ini::Ini;
/// let input = "[sec]\n";
/// let ini = Ini::load_from_str(input).unwrap();
/// assert_eq!(ini.get_from_or(Some("sec"), "key", "default"), "default");
/// ```
pub fn get_from_or<'a, S>(&'a self, section: Option<S>, key: &str, default: &'a str) -> &'a str
- where S: Into<String>
+ where
+ S: Into<String>,
{
match self.sections.get(§ion.map(|s| s.into())) {
None => default,
- Some(ref prop) => {
- match prop.get(key) {
- Some(p) => &p[..],
- None => default,
- }
- }
+ Some(ref prop) => match prop.get(key) {
+ Some(p) => &p[..],
+ None => default,
+ },
}
}
/// Get the mutable from a section with key
pub fn get_from_mut<'a, S>(&'a mut self, section: Option<S>, key: &str) -> Option<&'a str>
- where S: Into<String>
+ where
+ S: Into<String>,
{
match self.sections.get_mut(§ion.map(|s| s.into())) {
None => None,
Some(prop) => prop.get_mut(key).map(|s| &s[..]),
}
}
/// Delete a section, return the properties if it exists
pub fn delete<S>(&mut self, section: Option<S>) -> Option<Properties>
- where S: Into<String>
+ where
+ S: Into<String>,
{
self.sections.remove(§ion.map(|s| s.into()))
}
pub fn delete_from<S>(&mut self, section: Option<S>, key: &str) -> Option<String>
- where S: Into<String>
+ where
+ S: Into<String>,
{
match self.section_mut(section) {
None => return None,
Some(prop) => prop.remove(key),
}
}
}
@@ -378,38 +388,42 @@ impl<'q> IndexMut<&'q str> for Ini {
impl Ini {
/// Write to a file
pub fn write_to_file<P: AsRef<Path>>(&self, filename: P) -> io::Result<()> {
self.write_to_file_policy(filename, EscapePolicy::Basics)
}
/// Write to a file
- pub fn write_to_file_policy<P: AsRef<Path>>(&self,
- filename: P,
- policy: EscapePolicy)
- -> io::Result<()> {
- let mut file = try!(OpenOptions::new()
- .write(true)
- .truncate(true)
- .create(true)
- .open(filename.as_ref()));
+ pub fn write_to_file_policy<P: AsRef<Path>>(
+ &self,
+ filename: P,
+ policy: EscapePolicy,
+ ) -> io::Result<()> {
+ let mut file = try!(
+ OpenOptions::new()
+ .write(true)
+ .truncate(true)
+ .create(true)
+ .open(filename.as_ref())
+ );
self.write_to_policy(&mut file, policy)
}
/// Write to a writer
pub fn write_to<W: Write>(&self, writer: &mut W) -> io::Result<()> {
self.write_to_policy(writer, EscapePolicy::Basics)
}
/// Write to a writer
- pub fn write_to_policy<W: Write>(&self,
- writer: &mut W,
- policy: EscapePolicy)
- -> io::Result<()> {
+ pub fn write_to_policy<W: Write>(
+ &self,
+ writer: &mut W,
+ policy: EscapePolicy,
+ ) -> io::Result<()> {
let mut firstline = true;
match self.sections.get(&None) {
Some(props) => {
for (k, v) in props.iter() {
let k_str = escape_str(&k[..], policy);
let v_str = escape_str(&v[..], policy);
try!(write!(writer, "{}={}\n", k_str, v_str));
@@ -451,36 +465,32 @@ impl Ini {
pub fn load_from_str_noescape(buf: &str) -> Result<Ini, Error> {
let mut parser = Parser::new(buf.chars(), true);
parser.parse()
}
/// Load from a reader
pub fn read_from<R: Read>(reader: &mut R) -> Result<Ini, Error> {
let mut s = String::new();
- try!(reader.read_to_string(&mut s).map_err(|err| {
- Error {
- line: 0,
- col: 0,
- msg: format!("{}", err),
- }
+ try!(reader.read_to_string(&mut s).map_err(|err| Error {
+ line: 0,
+ col: 0,
+ msg: format!("{}", err),
}));
let mut parser = Parser::new(s.chars(), false);
parser.parse()
}
/// Load from a reader, but do not interpret '\' as an escape character
pub fn read_from_noescape<R: Read>(reader: &mut R) -> Result<Ini, Error> {
let mut s = String::new();
- try!(reader.read_to_string(&mut s).map_err(|err| {
- Error {
- line: 0,
- col: 0,
- msg: format!("{}", err),
- }
+ try!(reader.read_to_string(&mut s).map_err(|err| Error {
+ line: 0,
+ col: 0,
+ msg: format!("{}", err),
}));
let mut parser = Parser::new(s.chars(), true);
parser.parse()
}
/// Load from a file
pub fn load_from_file<P: AsRef<Path>>(filename: P) -> Result<Ini, Error> {
let mut reader = match File::open(filename.as_ref()) {
@@ -520,28 +530,34 @@ pub struct SectionIterator<'a> {
/// Iterator for mutable sections
pub struct SectionMutIterator<'a> {
mapiter: IterMut<'a, Option<String>, Properties>,
}
impl<'a> Ini {
/// Immutable iterate though sections
pub fn iter(&'a self) -> SectionIterator<'a> {
- SectionIterator { mapiter: self.sections.iter() }
+ SectionIterator {
+ mapiter: self.sections.iter(),
+ }
}
/// Mutable iterate though sections
/// *Deprecated! Use `iter_mut` instead!*
pub fn mut_iter(&'a mut self) -> SectionMutIterator<'a> {
- SectionMutIterator { mapiter: self.sections.iter_mut() }
+ SectionMutIterator {
+ mapiter: self.sections.iter_mut(),
+ }
}
/// Mutable iterate though sections
pub fn iter_mut(&'a mut self) -> SectionMutIterator<'a> {
- SectionMutIterator { mapiter: self.sections.iter_mut() }
+ SectionMutIterator {
+ mapiter: self.sections.iter_mut(),
+ }
}
}
impl<'a> Iterator for SectionIterator<'a> {
type Item = (&'a Option<String>, &'a Properties);
#[inline]
fn next(&mut self) -> Option<(&'a Option<String>, &'a Properties)> {
@@ -587,17 +603,19 @@ impl Iterator for SectionIntoIter {
}
}
impl IntoIterator for Ini {
type Item = (Option<String>, Properties);
type IntoIter = SectionIntoIter;
fn into_iter(self) -> SectionIntoIter {
- SectionIntoIter { iter: self.sections.into_iter() }
+ SectionIntoIter {
+ iter: self.sections.into_iter(),
+ }
}
}
// Ini parser
struct Parser<'a> {
ch: Option<char>,
rdr: Chars<'a>,
line: usize,
@@ -692,61 +710,56 @@ impl<'a> Parser<'a> {
/// Parse the whole INI input
pub fn parse(&mut self) -> Result<Ini, Error> {
let mut result = Ini::new();
let mut curkey: String = "".into();
let mut cursec: Option<String> = None;
self.parse_whitespace();
while let Some(cur_ch) = self.ch {
- debug!("line:{}, col:{}", self.line, self.col);
match cur_ch {
';' | '#' => {
self.parse_comment();
- debug!("parse comment");
}
- '[' => {
- match self.parse_section() {
- Ok(sec) => {
- let msec = &sec[..].trim();
- debug!("Got section: {}", msec);
- cursec = Some(msec.to_string());
- result.sections.entry(cursec.clone()).or_insert(HashMap::new());
- self.bump();
- }
- Err(e) => return Err(e),
+ '[' => match self.parse_section() {
+ Ok(sec) => {
+ let msec = &sec[..].trim();
+ cursec = Some(msec.to_string());
+ result
+ .sections
+ .entry(cursec.clone())
+ .or_insert(HashMap::new());
+ self.bump();
}
- }
+ Err(e) => return Err(e),
+ },
'=' | ':' => {
if (&curkey[..]).is_empty() {
return self.error("Missing key".to_string());
}
match self.parse_val() {
Ok(val) => {
let mval = val[..].trim().to_owned();
- debug!("Got value: {}", mval);
- let sec = result.sections
+ let sec = result
+ .sections
.entry(cursec.clone())
.or_insert(HashMap::new());
sec.insert(curkey, mval);
curkey = "".into();
}
Err(e) => return Err(e),
}
}
- _ => {
- match self.parse_key() {
- Ok(key) => {
- let mkey: String = key[..].trim().to_owned();
- debug!("Got key: {}", mkey);
- curkey = mkey.into();
- }
- Err(e) => return Err(e),
+ _ => match self.parse_key() {
+ Ok(key) => {
+ let mkey: String = key[..].trim().to_owned();
+ curkey = mkey.into();
}
- }
+ Err(e) => return Err(e),
+ },
}
self.parse_whitespace();
}
Ok(result)
}
@@ -781,24 +794,28 @@ impl<'a> Parser<'a> {
'n' => result.push('\n'),
'\n' => (),
'x' => {
// Unicode 4 character
let mut code: String = String::with_capacity(4);
for _ in 0..4 {
self.bump();
if self.eof() {
- return self.error(format!("Expecting \"{:?}\" but found EOF.",
- endpoint));
+ return self.error(format!(
+ "Expecting \"{:?}\" but found EOF.",
+ endpoint
+ ));
} else if let Some('\\') = self.ch {
self.bump();
if self.ch != Some('\n') {
- return self.error(format!("Expecting \"\\\\n\" but \
- found \"{:?}\".",
- self.ch));
+ return self.error(format!(
+ "Expecting \"\\\\n\" but \
+ found \"{:?}\".",
+ self.ch
+ ));
}
}
code.push(self.ch.unwrap());
}
let r = u32::from_str_radix(&code[..], 16);
match r {
Ok(c) => result.push(char::from_u32(c).unwrap()),
Err(_) => return self.error("Unknown character.".to_string()),
@@ -873,17 +890,16 @@ mod test {
let key1: String = "key1".into();
assert!(sec1.contains_key(&key1));
let key2: String = "key2".into();
assert!(sec1.contains_key(&key2));
let val1: String = "val1".into();
assert_eq!(sec1[&key1], val1);
let val2: String = "377".into();
assert_eq!(sec1[&key2], val2);
-
}
#[test]
fn load_from_str_without_ending_newline() {
let input = "[sec1]\nkey1=val1\nkey2=377\n[sec2]foo=bar";
let opt = Ini::load_from_str(input);
assert!(opt.is_ok());
}
@@ -935,18 +951,20 @@ gender = mail ; abdddd
fn test_colon() {
let input = "
[section name]
name: hello # abcdefg
gender : mail ; abdddd
";
let ini = Ini::load_from_str(input).unwrap();
assert_eq!(ini.get_from(Some("section name"), "name").unwrap(), "hello");
- assert_eq!(ini.get_from(Some("section name"), "gender").unwrap(),
- "mail");
+ assert_eq!(
+ ini.get_from(Some("section name"), "gender").unwrap(),
+ "mail"
+ );
}
#[test]
fn test_string() {
let input = "
[section name]
# This is a comment
Key = \"Value\"
@@ -959,31 +977,35 @@ Key = \"Value\"
fn test_string_multiline() {
let input = "
[section name]
# This is a comment
Key = \"Value
Otherline\"
";
let ini = Ini::load_from_str(input).unwrap();
- assert_eq!(ini.get_from(Some("section name"), "Key").unwrap(),
- "Value\nOtherline");
+ assert_eq!(
+ ini.get_from(Some("section name"), "Key").unwrap(),
+ "Value\nOtherline"
+ );
}
#[test]
fn test_string_comment() {
let input = "
[section name]
# This is a comment
Key = \"Value # This is not a comment ; at all\"
Stuff = Other
";
let ini = Ini::load_from_str(input).unwrap();
- assert_eq!(ini.get_from(Some("section name"), "Key").unwrap(),
- "Value # This is not a comment ; at all");
+ assert_eq!(
+ ini.get_from(Some("section name"), "Key").unwrap(),
+ "Value # This is not a comment ; at all"
+ );
}
#[test]
fn test_string_single() {
let input = "
[section name]
# This is a comment
Key = 'Value'
@@ -996,44 +1018,50 @@ Stuff = Other
#[test]
fn test_string_includes_quote() {
let input = "
[Test]
Comment[tr]=İnternet'e erişin
Comment[uk]=Доступ до Інтернету
";
let ini = Ini::load_from_str(input).unwrap();
- assert_eq!(ini.get_from(Some("Test"), "Comment[tr]").unwrap(),
- "İnternet'e erişin");
+ assert_eq!(
+ ini.get_from(Some("Test"), "Comment[tr]").unwrap(),
+ "İnternet'e erişin"
+ );
}
#[test]
fn test_string_single_multiline() {
let input = "
[section name]
# This is a comment
Key = 'Value
Otherline'
Stuff = Other
";
let ini = Ini::load_from_str(input).unwrap();
- assert_eq!(ini.get_from(Some("section name"), "Key").unwrap(),
- "Value\nOtherline");
+ assert_eq!(
+ ini.get_from(Some("section name"), "Key").unwrap(),
+ "Value\nOtherline"
+ );
}
#[test]
fn test_string_single_comment() {
let input = "
[section name]
# This is a comment
Key = 'Value # This is not a comment ; at all'
";
let ini = Ini::load_from_str(input).unwrap();
- assert_eq!(ini.get_from(Some("section name"), "Key").unwrap(),
- "Value # This is not a comment ; at all");
+ assert_eq!(
+ ini.get_from(Some("section name"), "Key").unwrap(),
+ "Value # This is not a comment ; at all"
+ );
}
#[test]
fn load_from_str_with_valid_empty_input() {
let input = "key1=\nkey2=val2\n";
let opt = Ini::load_from_str(input);
assert!(opt.is_ok());