Skip to content

Commit

Permalink
Add impl Encode for [T], where T: Encode (#542)
Browse files Browse the repository at this point in the history
* 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]
  • Loading branch information
cronokirby authored Jun 5, 2022
1 parent dcda3a8 commit e8ccb0a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 35 deletions.
40 changes: 18 additions & 22 deletions src/enc/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
13 changes: 0 additions & 13 deletions src/features/impl_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e8ccb0a

Please sign in to comment.