Skip to content

Commit 7d70b73

Browse files
authored
feat: Support serializing serde_bytes::Bytes as hex string literals (#250)
1 parent c75c2f2 commit 7d70b73

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/sql/escape.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ pub(crate) fn escape(src: &str, dst: &mut impl fmt::Write) -> fmt::Result {
2929
dst.write_str(rest)
3030
}
3131

32+
// See https://clickhouse.com/docs/en/sql-reference/syntax#string
33+
pub(crate) fn hex_bytes(s: &[u8], dst: &mut impl fmt::Write) -> fmt::Result {
34+
dst.write_char('X')?;
35+
dst.write_char('\'')?;
36+
for &byte in s {
37+
write!(dst, "{byte:02X}")?;
38+
}
39+
dst.write_char('\'')
40+
}
41+
3242
#[test]
3343
fn it_escapes_string() {
3444
let mut actual = String::new();

src/sql/ser.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,16 @@ impl<'a, W: Write> Serializer for SqlSerializer<'a, W> {
8585

8686
unsupported!(
8787
serialize_map(Option<usize>) -> Result<Impossible>,
88-
serialize_bytes(&[u8]),
8988
serialize_unit,
9089
serialize_unit_struct(&'static str),
9190
);
9291

92+
#[inline]
93+
fn serialize_bytes(self, value: &[u8]) -> Result {
94+
escape::hex_bytes(value, self.writer)?;
95+
Ok(())
96+
}
97+
9398
forward_to_display!(
9499
serialize_i8(i8),
95100
serialize_i16(i16),
@@ -458,6 +463,33 @@ mod tests {
458463
out
459464
}
460465

466+
#[test]
467+
fn it_writes_bytes() {
468+
use serde_bytes::ByteArray;
469+
use serde_bytes::ByteBuf;
470+
use serde_bytes::Bytes;
471+
472+
assert_eq!(check(Bytes::new(b"hello")), "X'68656C6C6F'");
473+
assert_eq!(check(Bytes::new(b"")), "X''");
474+
assert_eq!(check(Bytes::new(b"a\xffb")), "X'61FF62'");
475+
assert_eq!(check(Bytes::new(b"a'b")), "X'612762'");
476+
477+
assert_eq!(check(ByteArray::new(*b"hello")), "X'68656C6C6F'");
478+
assert_eq!(check(ByteArray::new(*b"")), "X''");
479+
assert_eq!(check(ByteArray::new(*b"a\xffb")), "X'61FF62'");
480+
assert_eq!(check(ByteArray::new(*b"a'b")), "X'612762'");
481+
482+
assert_eq!(check(ByteBuf::from(b"hello")), "X'68656C6C6F'");
483+
assert_eq!(check(ByteBuf::from(b"")), "X''");
484+
assert_eq!(check(ByteBuf::from(b"a\xffb")), "X'61FF62'");
485+
assert_eq!(check(ByteBuf::from(b"a'b")), "X'612762'");
486+
487+
assert_eq!(check(b"hello"), "(104,101,108,108,111)");
488+
assert_eq!(check(b""), "()");
489+
assert_eq!(check(b"a\xffb"), "(97,255,98)");
490+
assert_eq!(check(b"a'b"), "(97,39,98)");
491+
}
492+
461493
#[test]
462494
fn it_writes_numeric_primitives() {
463495
assert_eq!(check(42), "42");

0 commit comments

Comments
 (0)