diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 7c6c345..1741d61 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -6,12 +6,6 @@ == [Unreleased] -== [v0.2.1] - 2022-12-28 - -=== Fixed - -- fix serializing Unicode - == [v0.2.0] - 2022-11-25 === Added diff --git a/Cargo.toml b/Cargo.toml index 257207f..b979e20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_sjson" -version = "0.2.1" +version = "0.2.0" edition = "2021" keywords = ["serde", "serialization", "sjson"] description = "An SJSON serialization file format" diff --git a/src/ser.rs b/src/ser.rs index a10c566..51c9fd5 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -121,31 +121,48 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer { fn serialize_str(self, v: &str) -> Result { self.ensure_top_level_struct()?; - let needs_escapes = v.is_empty() || v.contains([' ', '\n', '\r', '\t', '=', '\'', '"', '\\', '/']); - if needs_escapes { self.output += "\""; - for c in v.chars() { + let len = v.len(); + let chars = v.chars(); + let mut start = 0; + + for (i, c) in chars.enumerate() { + if ('\x20'..='\x7e').contains(&c) + && !['\t', '\n', '\r', '\"', '\\', '/'].contains(&c) + { + continue; + } + + self.output += &v[start..i]; + self.output.push('\\'); + match c { '\t' => { - self.output.push('\\'); self.output.push('t'); } '\n' => { - self.output.push('\\'); self.output.push('n'); } '\r' => { - self.output.push('\\'); self.output.push('r'); } + '\x7f'.. => { + self.output += &format!("u{:4x}", c as u32); + } c => { self.output.push(c); } }; + + start = i + 1; + } + + if start < len { + self.output += &v[start..]; } self.output += "\"";