From 2ba6ee356e4567ff514b543deae5b6d995c79982 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Fri, 5 Apr 2024 10:22:24 +0200 Subject: [PATCH] Handle bytes identifier as UTF-8 strings Previously, we visited either strings or bytes so that the visitor had to handle both cases. With this change, we always visit strings so that the bytes visitor function can be optimized out. This significantly reduces binary size. --- src/de.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/de.rs b/src/de.rs index 4d58ca4..07041b9 100644 --- a/src/de.rs +++ b/src/de.rs @@ -808,9 +808,16 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { let major = self.peek_major()?; match major { - MAJOR_STR => self.deserialize_str(visitor), + MAJOR_BYTES | MAJOR_STR => { + // Rust identifiers are always valid UTF-8 so we can assume that bytes are + // UTF-8-encoded strings. This has the benefit that we only need a mapping from + // strings to fields (and the mapping from bytes to fields can be optimized out). + let length = self.raw_deserialize_u32(major)? as usize; + let bytes: &'de [u8] = self.try_take_n(length)?; + let string_slice = core::str::from_utf8(bytes).map_err(|_| Error::DeserializeBadUtf8)?; + visitor.visit_borrowed_str(string_slice) + } MAJOR_POSINT => self.deserialize_u64(visitor), - MAJOR_BYTES => self.deserialize_bytes(visitor), _ => Err(Error::DeserializeBadMajor), } }