From e8ccb0a0e95557698a52977a2e829951bf5eba9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=BAc=C3=A1s=20Meier?= Date: Sun, 5 Jun 2022 18:41:43 +0200 Subject: [PATCH] Add impl Encode for [T], where T: Encode (#542) * Add impl Encode for [T], where T: Encode Since Encode takes a reference, this allows us to encode &[T] directly using this implementation. The encoding scheme is the same as for Vec. This also makes the implementation for &[u8] superfluous, since we get an implementation for [u8] by virtue of u8 implementing encode. This also gives us free implementations for &[u16], &[u32], etc. which is quite useful. Nonetheless, we keep the implementation for &[u8] around, because the implementation can directly write a large number of bytes, which can be more efficient than the generic implementation. * Remove redundant Encode implementations Since we've implemented Encode for [T], this makes the implementation for Box<[T]> redundant (since we have a blanket implementation for Box), and ditto for &[T], which this change replaces by combining the implementations for [T] and &T. * Reinclude comment about Encode specialization for &[u8] --- src/enc/impls.rs | 40 +++++++++++++++++--------------------- src/features/impl_alloc.rs | 13 ------------- 2 files changed, 18 insertions(+), 35 deletions(-) diff --git a/src/enc/impls.rs b/src/enc/impls.rs index 40e7234c..271f92ae 100644 --- a/src/enc/impls.rs +++ b/src/enc/impls.rs @@ -283,13 +283,29 @@ impl Encode for char { } } +// BlockedTODO: https://github.com/rust-lang/rust/issues/37653 +// +// We'll want to implement encoding for both &[u8] and &[T: Encode], +// but those implementations overlap because u8 also implements Encode // impl Encode for &'_ [u8] { // fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { -// super::encode_slice_len(encoder, self.len())?; -// encoder.writer().write(self) +// encoder.writer().write(*self) // } // } +impl Encode for [T] +where + T: Encode, +{ + fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { + super::encode_slice_len(encoder, self.len())?; + for item in self { + item.encode(encoder)?; + } + Ok(()) + } +} + const TAG_CONT: u8 = 0b1000_0000; const TAG_TWO_B: u8 = 0b1100_0000; const TAG_THREE_B: u8 = 0b1110_0000; @@ -324,26 +340,6 @@ fn encode_utf8(writer: &mut impl Writer, c: char) -> Result<(), EncodeError> { } } -// BlockedTODO: https://github.com/rust-lang/rust/issues/37653 -// -// We'll want to implement encoding for both &[u8] and &[T: Encode], -// but those implementations overlap because u8 also implements Encode -// impl Encode for &'_ [u8] { -// fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { -// encoder.writer().write(*self) -// } -// } - -impl Encode for &'_ [T] { - fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { - self.len().encode(encoder)?; - for item in self.iter() { - item.encode(encoder)?; - } - Ok(()) - } -} - impl Encode for str { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { self.as_bytes().encode(encoder) diff --git a/src/features/impl_alloc.rs b/src/features/impl_alloc.rs index c56d7359..62449fb3 100644 --- a/src/features/impl_alloc.rs +++ b/src/features/impl_alloc.rs @@ -375,19 +375,6 @@ where } } -impl Encode for Box<[T]> -where - T: Encode, -{ - fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { - crate::enc::encode_slice_len(encoder, self.len())?; - for item in self.iter() { - item.encode(encoder)?; - } - Ok(()) - } -} - impl<'cow, T> Decode for Cow<'cow, T> where T: ToOwned + ?Sized,