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<T>.

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<T>), and ditto for &[T], which this change replaces by combining the
implementations for [T] and &T.

* Reinclude comment about Encode specialization for &[u8]
This commit is contained in:
Lúcás Meier 2022-06-05 18:41:43 +02:00 committed by GitHub
parent 86e03aeda7
commit 357d7d3c0e
2 changed files with 18 additions and 35 deletions

View File

@ -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<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
// super::encode_slice_len(encoder, self.len())?;
// encoder.writer().write(self)
// encoder.writer().write(*self)
// }
// }
impl<T> Encode for [T]
where
T: Encode,
{
fn encode<E: Encoder>(&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<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
// encoder.writer().write(*self)
// }
// }
impl<T: Encode> Encode for &'_ [T] {
fn encode<E: Encoder>(&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<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
self.as_bytes().encode(encoder)

View File

@ -375,19 +375,6 @@ where
}
}
impl<T> Encode for Box<[T]>
where
T: Encode,
{
fn encode<E: Encoder>(&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,