From c873704efc9f5cb6e50346e83a45e7b85b484beb Mon Sep 17 00:00:00 2001 From: hoang Date: Sat, 15 Jul 2023 10:56:09 +0700 Subject: [PATCH] Implement `SerJson` for `str` --- src/serde_json.rs | 43 +++++++++++++++++++++++++------------------ tests/json.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/serde_json.rs b/src/serde_json.rs index 7e69d8d..bdd7b2d 100644 --- a/src/serde_json.rs +++ b/src/serde_json.rs @@ -778,29 +778,36 @@ impl DeJson for bool { } } -impl SerJson for String { - fn ser_json(&self, _d: usize, s: &mut SerJsonState) { - s.out.push('"'); - for c in self.chars() { - match c { - '\x08' => s.out += "\\b", - '\x0C' => s.out += "\\f", - '\n' => s.out += "\\n", - '\r' => s.out += "\\r", - '\t' => s.out += "\\t", - _ if c.is_ascii_control() => { - use core::fmt::Write as _; - let _ = write!(s.out, "\\u{:04x}", c as u32); +macro_rules! impl_ser_json_string { + ($ty: ident) => { + impl SerJson for $ty { + fn ser_json(&self, _d: usize, s: &mut SerJsonState) { + s.out.push('"'); + for c in self.chars() { + match c { + '\x08' => s.out += "\\b", + '\x0C' => s.out += "\\f", + '\n' => s.out += "\\n", + '\r' => s.out += "\\r", + '\t' => s.out += "\\t", + _ if c.is_ascii_control() => { + use core::fmt::Write as _; + let _ = write!(s.out, "\\u{:04x}", c as u32); + } + '\\' => s.out += "\\\\", + '"' => s.out += "\\\"", + _ => s.out.push(c), + } } - '\\' => s.out += "\\\\", - '"' => s.out += "\\\"", - _ => s.out.push(c), + s.out.push('"'); } } - s.out.push('"'); - } + }; } +impl_ser_json_string!(String); +impl_ser_json_string!(str); + impl DeJson for String { fn de_json(s: &mut DeJsonState, i: &mut Chars) -> Result { let val = s.as_string()?; diff --git a/tests/json.rs b/tests/json.rs index 8ba3bec..ae821c7 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -691,3 +691,41 @@ fn control_characters() { assert_eq!(SerJson::serialize_json(&string), escaped); } + +#[test] +fn ser_str() { + #[derive(SerJson)] + struct AString { + s: String, + } + + #[derive(SerJson)] + struct ABorrowedString<'a> { + s: &'a String, + } + + #[derive(SerJson)] + struct AStr<'a> { + s: &'a str, + } + + let a_string = AString { + s: "abc".to_string(), + }; + + let a_borrowed_string = ABorrowedString { + s: &"abc".to_string(), + }; + + let a_str = AStr { s: "abc" }; + + assert_eq!( + SerJson::serialize_json(&a_string), + SerJson::serialize_json(&a_borrowed_string) + ); + + assert_eq!( + SerJson::serialize_json(&a_string), + SerJson::serialize_json(&a_str) + ); +}