diff --git a/Cargo.toml b/Cargo.toml index 0c71b83..85b00a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rust-ini" -version = "0.15.1" +version = "0.15.2" authors = ["Y. T. Chung "] description = "An Ini configuration file parsing library in Rust" repository = "https://github.com/zonyitoo/rust-ini" diff --git a/src/ini.rs b/src/ini.rs index 3e90ec4..e358dc7 100644 --- a/src/ini.rs +++ b/src/ini.rs @@ -83,7 +83,9 @@ impl EscapePolicy { /// 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(), + // A single backslash, must be escaped + // ASCII control characters, U+0000 NUL..= U+001F UNIT SEPARATOR, or U+007F DELETE. The same as char::is_ascii_control() + '\\' | '\x00'..='\x1f' | '\x7f' => self.escape_basics(), ';' | '#' | '=' | ':' => self.escape_reserved(), '\u{0080}'..='\u{FFFF}' => self.escape_unicode(), _ => false, @@ -110,6 +112,8 @@ impl EscapePolicy { fn escape_str(s: &str, policy: EscapePolicy) -> String { let mut escaped: String = String::with_capacity(s.len()); for c in s.chars() { + println!("SHOULD? {} {} {}", c, policy.should_escape(c), c.escape_unicode()); + // if we know this is not something to escape as per policy, we just // write it and continue. if !policy.should_escape(c) { @@ -213,6 +217,7 @@ impl LineSeparator { } /// Writing configuration +#[derive(Debug, Clone)] pub struct WriteOption { /// Policies about how to escape characters pub escape_policy: EscapePolicy, @@ -1732,4 +1737,16 @@ bar = f let v = conf.get_from(Some(section), key).unwrap(); assert_eq!(v, new_value); } + + #[test] + fn fix_issue64() { + let input = format!("some-key=åäö{}", super::DEFAULT_LINE_SEPARATOR); + + let conf = Ini::load_from_str(&input).unwrap(); + + let mut output = Vec::new(); + conf.write_to_policy(&mut output, EscapePolicy::Basics).unwrap(); + + assert_eq!(input, String::from_utf8(output).unwrap()); + } }