Unverified Commit b5d2ea7f authored by thiolliere's avatar thiolliere Committed by GitHub
Browse files

make `Output` trait object and encode_to allowed on not sized `Output` (#239)

parent c116844e
Pipeline #120212 passed with stages
in 19 minutes and 9 seconds
......@@ -74,7 +74,7 @@ fn encode_single_field(
let i_self = quote! { self };
quote_spanned! { field.span() =>
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>(
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>(
&#i_self,
__codec_dest_edqy: &mut __CodecOutputEdqy
) {
......@@ -117,9 +117,12 @@ fn encode_fields<F>(
let field_type = &f.ty;
quote_spanned! {
f.span() => {
#dest.push(
&<<#field_type as _parity_scale_codec::HasCompact>::Type as
_parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field)
_parity_scale_codec::Encode::encode_to(
&<
<#field_type as _parity_scale_codec::HasCompact>::Type as
_parity_scale_codec::EncodeAsRef<'_, #field_type>
>::RefType::from(#field),
#dest,
);
}
}
......@@ -127,9 +130,12 @@ fn encode_fields<F>(
let field_type = &f.ty;
quote_spanned! {
f.span() => {
#dest.push(
&<#encoded_as as
_parity_scale_codec::EncodeAsRef<'_, #field_type>>::RefType::from(#field)
_parity_scale_codec::Encode::encode_to(
&<
#encoded_as as
_parity_scale_codec::EncodeAsRef<'_, #field_type>
>::RefType::from(#field),
#dest,
);
}
}
......@@ -139,7 +145,7 @@ fn encode_fields<F>(
}
} else {
quote_spanned! { f.span() =>
#dest.push(#field);
_parity_scale_codec::Encode::encode_to(#field, #dest);
}
}
});
......@@ -288,7 +294,10 @@ fn impl_encode(data: &Data, type_name: &Ident) -> TokenStream {
};
quote! {
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output>(&#self_, #dest: &mut __CodecOutputEdqy) {
fn encode_to<__CodecOutputEdqy: _parity_scale_codec::Output + ?Sized>(
&#self_,
#dest: &mut __CodecOutputEdqy
) {
#encoding
}
}
......
......@@ -22,7 +22,7 @@ use crate::compact::Compact;
use crate::EncodeLike;
impl<O: BitOrder, T: BitStore + Encode> Encode for BitSlice<O, T> {
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
let len = self.len();
assert!(
len <= u32::max_value() as usize,
......@@ -41,7 +41,7 @@ impl<O: BitOrder, T: BitStore + Encode> Encode for BitSlice<O, T> {
}
impl<O: BitOrder, T: BitStore + Encode> Encode for BitVec<O, T> {
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
self.as_bitslice().encode_to(dest)
}
}
......@@ -76,7 +76,7 @@ impl<O: BitOrder, T: BitStore + Decode> Decode for BitVec<O, T> {
}
impl<O: BitOrder, T: BitStore + Encode> Encode for BitBox<O, T> {
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
self.as_bitslice().encode_to(dest)
}
}
......
......@@ -211,7 +211,7 @@ impl<R: std::io::Read> Input for IoReader<R> {
}
/// Trait that allows writing of data.
pub trait Output: Sized {
pub trait Output {
/// Write to the output.
fn write(&mut self, bytes: &[u8]);
......@@ -219,11 +219,6 @@ pub trait Output: Sized {
fn push_byte(&mut self, byte: u8) {
self.write(&[byte]);
}
/// Write encoding of given value to the output.
fn push<V: Encode + ?Sized>(&mut self, value: &V) {
value.encode_to(self);
}
}
#[cfg(not(feature = "std"))]
......@@ -280,7 +275,7 @@ pub trait Encode {
}
/// Convert self to a slice and append it to the destination.
fn encode_to<T: Output>(&self, dest: &mut T) {
fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
self.using_encoded(|buf| dest.write(buf));
}
......@@ -396,7 +391,7 @@ impl<T, X> Encode for X where
(&**self).encode()
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
(&**self).encode_to(dest)
}
}
......@@ -471,7 +466,7 @@ impl<T: Encode, E: Encode> Encode for Result<T, E> {
}
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match *self {
Ok(ref t) => {
dest.push_byte(0);
......@@ -550,7 +545,7 @@ impl<T: Encode> Encode for Option<T> {
}
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match *self {
Some(ref t) => {
dest.push_byte(1);
......@@ -579,7 +574,7 @@ macro_rules! impl_for_non_zero {
self.get().size_hint()
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
self.get().encode_to(dest)
}
......@@ -605,7 +600,7 @@ macro_rules! impl_for_non_zero {
/// Encode the slice without prepending the len.
///
/// This is equivalent to encoding all the element one by one, but it is optimized for some types.
pub(crate) fn encode_slice_no_len<T: Encode, W: Output>(slice: &[T], dest: &mut W) {
pub(crate) fn encode_slice_no_len<T: Encode, W: Output + ?Sized>(slice: &[T], dest: &mut W) {
macro_rules! encode_to {
( u8, $slice:ident, $dest:ident ) => {{
let typed = unsafe { mem::transmute::<&[T], &[u8]>(&$slice[..]) };
......@@ -706,7 +701,7 @@ macro_rules! impl_array {
mem::size_of::<T>() * $n
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
encode_slice_no_len(&self[..], dest)
}
}
......@@ -755,7 +750,7 @@ impl Encode for str {
self.as_bytes().size_hint()
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
self.as_bytes().encode_to(dest)
}
......@@ -779,7 +774,7 @@ impl<'a, T: ToOwned + ?Sized> Decode for Cow<'a, T>
impl<T> EncodeLike for PhantomData<T> {}
impl<T> Encode for PhantomData<T> {
fn encode_to<W: Output>(&self, _dest: &mut W) {}
fn encode_to<W: Output + ?Sized>(&self, _dest: &mut W) {}
}
impl<T> Decode for PhantomData<T> {
......@@ -796,7 +791,7 @@ impl Decode for String {
}
/// Writes the compact encoding of `len` do `dest`.
pub(crate) fn compact_encode_len_to<W: Output>(dest: &mut W, len: usize) -> Result<(), Error> {
pub(crate) fn compact_encode_len_to<W: Output + ?Sized>(dest: &mut W, len: usize) -> Result<(), Error> {
if len > u32::max_value() as usize {
return Err("Attempted to serialize a collection with too many elements.".into());
}
......@@ -810,7 +805,7 @@ impl<T: Encode> Encode for [T] {
mem::size_of::<u32>() + mem::size_of::<T>() * self.len()
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
compact_encode_len_to(dest, self.len()).expect("Compact encodes length");
encode_slice_no_len(self, dest)
......@@ -908,7 +903,7 @@ macro_rules! impl_codec_through_iterator {
mem::size_of::<u32>() $( + mem::size_of::<$generics>() * self.len() )*
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
compact_encode_len_to(dest, self.len()).expect("Compact encodes length");
for i in self.iter() {
......@@ -961,7 +956,7 @@ impl<T: Encode> Encode for VecDeque<T> {
mem::size_of::<u32>() + mem::size_of::<T>() * self.len()
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
compact_encode_len_to(dest, self.len()).expect("Compact encodes length");
macro_rules! encode_to {
......@@ -1003,7 +998,7 @@ impl<T: Decode> Decode for VecDeque<T> {
impl EncodeLike for () {}
impl Encode for () {
fn encode_to<W: Output>(&self, _dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, _dest: &mut W) {
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
......@@ -1044,7 +1039,7 @@ macro_rules! tuple_impl {
self.0.size_hint()
}
fn encode_to<T: Output>(&self, dest: &mut T) {
fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
self.0.encode_to(dest);
}
......@@ -1085,7 +1080,7 @@ macro_rules! tuple_impl {
$( + $rest.size_hint() )+
}
fn encode_to<T: Output>(&self, dest: &mut T) {
fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
let (
ref $first,
$(ref $rest),+
......
......@@ -113,7 +113,7 @@ where
CompactRef(&self.0).size_hint()
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
CompactRef(&self.0).encode_to(dest)
}
......@@ -141,7 +141,7 @@ where
CompactRef(self.0.encode_as()).size_hint()
}
fn encode_to<Out: Output>(&self, dest: &mut Out) {
fn encode_to<Out: Output + ?Sized>(&self, dest: &mut Out) {
CompactRef(self.0.encode_as()).encode_to(dest)
}
......@@ -234,7 +234,7 @@ impl<T: 'static> HasCompact for T where
}
impl<'a> Encode for CompactRef<'a, ()> {
fn encode_to<W: Output>(&self, _dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, _dest: &mut W) {
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
......@@ -251,7 +251,7 @@ impl<'a> Encode for CompactRef<'a, u8> {
Compact::compact_len(self.0)
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match self.0 {
0..=0b0011_1111 => dest.push_byte(self.0 << 2),
_ => ((u16::from(*self.0) << 2) | 0b01).encode_to(dest),
......@@ -279,7 +279,7 @@ impl<'a> Encode for CompactRef<'a, u16> {
Compact::compact_len(self.0)
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match self.0 {
0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
0..=0b0011_1111_1111_1111 => ((*self.0 << 2) | 0b01).encode_to(dest),
......@@ -309,7 +309,7 @@ impl<'a> Encode for CompactRef<'a, u32> {
Compact::compact_len(self.0)
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match self.0 {
0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest),
......@@ -344,7 +344,7 @@ impl<'a> Encode for CompactRef<'a, u64> {
Compact::compact_len(self.0)
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match self.0 {
0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest),
......@@ -388,7 +388,7 @@ impl<'a> Encode for CompactRef<'a, u128> {
Compact::compact_len(self.0)
}
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
match self.0 {
0..=0b0011_1111 => dest.push_byte((*self.0 as u8) << 2),
0..=0b0011_1111_1111_1111 => (((*self.0 as u16) << 2) | 0b01).encode_to(dest),
......
......@@ -17,7 +17,7 @@ use crate::codec::{Encode, Decode, Input, Output, Error};
use crate::encode_like::EncodeLike;
impl<T: Encode, L: generic_array::ArrayLength<T>> Encode for generic_array::GenericArray<T, L> {
fn encode_to<W: Output>(&self, dest: &mut W) {
fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
for item in self.iter() {
item.encode_to(dest);
}
......
......@@ -14,7 +14,9 @@
#[cfg(not(feature="derive"))]
use parity_scale_codec_derive::{Encode, Decode};
use parity_scale_codec::{Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error};
use parity_scale_codec::{
Encode, Decode, HasCompact, Compact, EncodeAsRef, CompactAs, Error, Output,
};
use serde_derive::{Serialize, Deserialize};
#[derive(Debug, PartialEq, Encode, Decode)]
......@@ -548,3 +550,8 @@ fn weird_derive() {
make_struct!(#[derive(Encode, Decode)]);
}
#[test]
fn output_trait_object() {
let _: Box<dyn Output>;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment